using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Rendering.HighDefinition;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("MaskFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Misc fixes for mask items and enemies")]
[assembly: AssemblyFileVersion("1.2.2.0")]
[assembly: AssemblyInformationalVersion("1.2.2+16618bfb42b15a0085c1430de08c22126b8e2d92")]
[assembly: AssemblyProduct("MaskFixes")]
[assembly: AssemblyTitle("MaskFixes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.2.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MaskFixes
{
internal class NewMaskedAI
{
private static LayerMask hideLayers = LayerMask.op_Implicit(LayerMask.NameToLayer("Default") | LayerMask.NameToLayer("Room") | LayerMask.NameToLayer("Colliders") | LayerMask.NameToLayer("PlaceableShipObject") | LayerMask.NameToLayer("DecalStickableSurface"));
internal static Vector3 mainEntrancePoint;
internal static Vector3 mainEntrancePointOutside;
internal static Bounds startRoomBounds;
internal static void HideOnShip(MaskedPlayerEnemy maskedAI)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0180: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_01a0: 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_0060: 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)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < StartOfRound.Instance.insideShipPositions.Length; i++)
{
if (!Physics.Linecast(((Component)StartOfRound.Instance.shipDoorAudioSource).transform.position, StartOfRound.Instance.insideShipPositions[i].position, LayerMask.op_Implicit(hideLayers), (QueryTriggerInteraction)1) || !((EnemyAI)maskedAI).SetDestinationToPosition(StartOfRound.Instance.insideShipPositions[i].position, true))
{
continue;
}
maskedAI.shipHidingSpot = ((EnemyAI)maskedAI).destination;
bool flag = true;
foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
{
if (!spawnedEnemy.isEnemyDead)
{
MaskedPlayerEnemy val = (MaskedPlayerEnemy)(object)((spawnedEnemy is MaskedPlayerEnemy) ? spawnedEnemy : null);
if (val != null && (Object)(object)maskedAI != (Object)(object)val && ((EnemyAI)val).currentBehaviourStateIndex == 2 && Vector3.Distance(maskedAI.shipHidingSpot, val.shipHidingSpot) < 1.75f)
{
flag = false;
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)maskedAI).GetInstanceID()}: Can't choose hiding spot #{i}, already claimed by mimic #{((Object)val).GetInstanceID()}");
break;
}
}
}
if (flag)
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)maskedAI).GetInstanceID()}: Claimed hiding spot #{i} at coords {maskedAI.shipHidingSpot}");
return;
}
}
maskedAI.shipHidingSpot = StartOfRound.Instance.insideShipPositions[Random.Range(0, StartOfRound.Instance.insideShipPositions.Length)].position;
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)maskedAI).GetInstanceID()}: Fall back to position at coords {maskedAI.shipHidingSpot}");
}
internal static void Roam(MaskedPlayerEnemy maskedAI)
{
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0192: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: 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_027c: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_0281: Unknown result type (might be due to invalid IL or missing references)
//IL_0320: 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_02b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
//IL_0302: 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_02cc: Unknown result type (might be due to invalid IL or missing references)
maskedAI.LookAndRunRandomly(true, false);
PlayerControllerB val = ((EnemyAI)maskedAI).CheckLineOfSightForClosestPlayer(45f, 60, -1, 0f);
if ((Object)(object)val != (Object)null)
{
maskedAI.LookAtPlayerServerRpc((int)val.playerClientId);
((EnemyAI)maskedAI).SetMovingTowardsTargetPlayer(val);
((EnemyAI)maskedAI).SwitchToBehaviourState(1);
return;
}
maskedAI.interestInShipCooldown += ((EnemyAI)maskedAI).AIIntervalTime;
if (((EnemyAI)maskedAI).isOutside && maskedAI.interestInShipCooldown >= 17f && Vector3.Distance(((Component)maskedAI).transform.position, StartOfRound.Instance.elevatorTransform.position) < 22f)
{
((EnemyAI)maskedAI).SwitchToBehaviourState(2);
return;
}
PlayerControllerB val2 = null;
PlayerControllerB val3 = null;
float num = float.MaxValue;
float num2 = float.MaxValue;
for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
{
if ((Object)(object)StartOfRound.Instance.allPlayerScripts[i] == (Object)null || StartOfRound.Instance.allPlayerScripts[i].isPlayerDead || !StartOfRound.Instance.allPlayerScripts[i].isPlayerControlled)
{
continue;
}
if (StartOfRound.Instance.allPlayerScripts[i].isInsideFactory)
{
if (!((Object)(object)StartOfRound.Instance.allPlayerScripts[i].inAnimationWithEnemy != (Object)null))
{
((EnemyAI)maskedAI).tempDist = Vector3.Distance(((Component)maskedAI).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
if (((EnemyAI)maskedAI).tempDist < num)
{
num = ((EnemyAI)maskedAI).tempDist;
val2 = StartOfRound.Instance.allPlayerScripts[i];
}
}
}
else
{
((EnemyAI)maskedAI).tempDist = Vector3.Distance(((Component)maskedAI).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
if (((EnemyAI)maskedAI).tempDist < num2)
{
num2 = ((EnemyAI)maskedAI).tempDist;
val3 = StartOfRound.Instance.allPlayerScripts[i];
}
}
}
((EnemyAI)maskedAI).mostOptimalDistance = Mathf.Min(new float[3] { num2, num, 2000f });
if (RoundManager.Instance.currentDungeonType == 4 && (Object)(object)maskedAI.elevatorScript == (Object)null)
{
maskedAI.elevatorScript = RoundManager.Instance.currentMineshaftElevator;
}
bool flag = (Object)(object)val2 != (Object)null && (!((EnemyAI)maskedAI).isOutside || (Object)(object)val3 == (Object)null);
if (!UseElevatorIfNeeded(maskedAI, flag, val2))
{
if (maskedAI.searchForPlayers.inProgress)
{
((EnemyAI)maskedAI).StopSearch(maskedAI.searchForPlayers, true);
}
return;
}
Vector3 val4 = (((EnemyAI)maskedAI).isOutside ? mainEntrancePointOutside : mainEntrancePoint);
if (flag == ((EnemyAI)maskedAI).isOutside && Time.realtimeSinceStartup - maskedAI.timeAtLastUsingEntrance > 3f && CanPathToPoint(maskedAI, val4))
{
if (Vector3.Distance(((Component)maskedAI).transform.position, val4) < 1f)
{
maskedAI.TeleportMaskedEnemyAndSync(((EnemyAI)maskedAI).isOutside ? mainEntrancePoint : mainEntrancePointOutside, !((EnemyAI)maskedAI).isOutside);
return;
}
if (maskedAI.searchForPlayers.inProgress)
{
((EnemyAI)maskedAI).StopSearch(maskedAI.searchForPlayers, true);
}
((EnemyAI)maskedAI).SetDestinationToPosition(val4, false);
}
else if (!maskedAI.searchForPlayers.inProgress)
{
((EnemyAI)maskedAI).StartSearch(((Component)maskedAI).transform.position, maskedAI.searchForPlayers);
}
}
private static bool CanPathToPoint(MaskedPlayerEnemy maskedAI, Vector3 pos)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
((EnemyAI)maskedAI).pathDistance = 0f;
if (((EnemyAI)maskedAI).agent.isOnNavMesh && !((EnemyAI)maskedAI).agent.CalculatePath(pos, ((EnemyAI)maskedAI).path1))
{
return false;
}
if (((EnemyAI)maskedAI).path1 == null || ((EnemyAI)maskedAI).path1.corners.Length == 0)
{
return false;
}
if (Vector3.Distance(((EnemyAI)maskedAI).path1.corners[^1], RoundManager.Instance.GetNavMeshPosition(pos, RoundManager.Instance.navHit, 2.7f, ((EnemyAI)maskedAI).agent.areaMask)) > 1.5f)
{
return false;
}
return true;
}
private static bool UseElevatorIfNeeded(MaskedPlayerEnemy maskedAI, bool wantsToBeInside, PlayerControllerB closestInsidePlayer)
{
//IL_001e: 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_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0199: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
if (((EnemyAI)maskedAI).isOutside || (Object)(object)maskedAI.elevatorScript == (Object)null)
{
return true;
}
bool flag = Vector3.Distance(((Component)maskedAI).transform.position, maskedAI.elevatorScript.elevatorInsidePoint.position) < 1f;
if (flag && (!maskedAI.elevatorScript.elevatorFinishedMoving || !maskedAI.elevatorScript.elevatorDoorOpen))
{
return false;
}
maskedAI.isInElevatorStartRoom = ((Bounds)(ref startRoomBounds)).Contains(((Component)maskedAI).transform.position);
Vector3 val = (maskedAI.isInElevatorStartRoom ? maskedAI.elevatorScript.elevatorTopPoint.position : maskedAI.elevatorScript.elevatorBottomPoint.position);
bool flag2 = !wantsToBeInside && !maskedAI.isInElevatorStartRoom;
if (!flag2 && (Object)(object)closestInsidePlayer != (Object)null)
{
bool flag3 = ((Bounds)(ref startRoomBounds)).Contains(((Component)closestInsidePlayer).transform.position);
if (maskedAI.isInElevatorStartRoom != flag3)
{
flag2 = true;
}
}
if (!flag2 && !flag)
{
return true;
}
if (flag)
{
if (flag2 && maskedAI.elevatorScript.elevatorMovingDown != maskedAI.isInElevatorStartRoom)
{
maskedAI.elevatorScript.PressElevatorButtonOnServer(true);
return false;
}
if (!flag2 && maskedAI.elevatorScript.elevatorFinishedMoving && maskedAI.elevatorScript.elevatorDoorOpen)
{
if (CanPathToPoint(maskedAI, val))
{
((EnemyAI)maskedAI).SetDestinationToPosition(val, false);
}
return false;
}
}
if (flag2)
{
if (maskedAI.elevatorScript.elevatorFinishedMoving && maskedAI.elevatorScript.elevatorDoorOpen && maskedAI.elevatorScript.elevatorMovingDown != maskedAI.isInElevatorStartRoom)
{
if (CanPathToPoint(maskedAI, maskedAI.elevatorScript.elevatorInsidePoint.position))
{
((EnemyAI)maskedAI).SetDestinationToPosition(maskedAI.elevatorScript.elevatorInsidePoint.position, false);
}
return false;
}
if (Vector3.Distance(((Component)maskedAI).transform.position, val) < 1f)
{
if (maskedAI.elevatorScript.elevatorMovingDown == maskedAI.isInElevatorStartRoom && !maskedAI.elevatorScript.elevatorCalled)
{
maskedAI.elevatorScript.CallElevator(!maskedAI.isInElevatorStartRoom);
}
return false;
}
if (CanPathToPoint(maskedAI, val))
{
((EnemyAI)maskedAI).SetDestinationToPosition(val, false);
}
return false;
}
Plugin.Logger.LogWarning((object)"Masked elevator behavior seems to be stuck in an impossible state");
return false;
}
}
[HarmonyPatch(typeof(MaskedPlayerEnemy))]
internal class Patches
{
private static Mesh TRAGEDY_MASK;
private static Mesh TRAGEDY_MASK_LOD;
private static Mesh TRAGEDY_EYES_FILLED;
private static Material TRAGEDY_MAT;
private static AudioClip[] TRAGEDY_RANDOM_CLIPS;
private static float localPlayerLastTeleported;
private static float safeTimer;
private const int PURPLE_SUIT_ID = 24;
private static readonly List<int> suitIndices = new List<int>(7) { 0, 1, 2, 3, 24, 25, 26 };
[HarmonyPatch(typeof(StartOfRound), "Awake")]
[HarmonyPostfix]
private static void StartOfRound_Post_Awake(StartOfRound __instance)
{
GameObject val = __instance.playerRagdolls?.FirstOrDefault((Func<GameObject, bool>)((GameObject playerRagdoll) => ((Object)playerRagdoll).name == "PlayerRagdollWithTragedyMask Variant"));
if ((Object)(object)val != (Object)null)
{
MeshFilter[] componentsInChildren = val.GetComponentsInChildren<MeshFilter>();
foreach (MeshFilter val2 in componentsInChildren)
{
switch (((Object)val2).name)
{
case "Mesh":
{
TRAGEDY_MASK = val2.sharedMesh;
Plugin.Logger.LogDebug((object)"Cached Tragedy model");
MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>();
TRAGEDY_MAT = ((component != null) ? ((Renderer)component).sharedMaterial : null);
Plugin.Logger.LogDebug((object)"Cached Tragedy material");
break;
}
case "ComedyMaskLOD1":
TRAGEDY_MASK_LOD = val2.sharedMesh;
Plugin.Logger.LogDebug((object)"Cached Tragedy LOD");
break;
case "EyesFilled":
TRAGEDY_EYES_FILLED = val2.sharedMesh;
Plugin.Logger.LogDebug((object)"Cached Tragedy glowing eyes");
break;
}
}
}
else
{
Plugin.Logger.LogWarning((object)"Failed to find reference to Tragedy ragdoll. This will cause problems later!!");
}
GameObject val3 = __instance.allItemsList?.itemsList?.FirstOrDefault((Func<Item, bool>)((Item item) => ((Object)item).name == "TragedyMask"))?.spawnPrefab;
if ((Object)(object)val3 != (Object)null)
{
TRAGEDY_RANDOM_CLIPS = val3.GetComponent<RandomPeriodicAudioPlayer>()?.randomClips;
Plugin.Logger.LogDebug((object)"Cached Tragedy random audio");
Transform obj = val3.transform.Find("MaskMesh");
MeshFilter val4 = ((obj != null) ? ((Component)obj).GetComponent<MeshFilter>() : null);
if ((Object)(object)val4 != (Object)null)
{
Transform obj2 = ((Component)val4).transform.Find("EyesFilled");
MeshFilter val5 = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshFilter>() : null);
if ((Object)(object)val5 != (Object)null && (Object)(object)TRAGEDY_EYES_FILLED != (Object)null)
{
val5.mesh = TRAGEDY_EYES_FILLED;
Plugin.Logger.LogDebug((object)"Tragedy mask: Re-assigned glowing eyes");
}
Transform obj3 = ((Component)val4).transform.Find("ComedyMaskLOD1");
MeshFilter val6 = ((obj3 != null) ? ((Component)obj3).GetComponent<MeshFilter>() : null);
if ((Object)(object)val6 != (Object)null && (Object)(object)TRAGEDY_MASK_LOD != (Object)null)
{
val6.mesh = TRAGEDY_MASK_LOD;
Plugin.Logger.LogDebug((object)"Tragedy mask: Re-assigned LOD");
}
}
}
else
{
Plugin.Logger.LogWarning((object)"Failed to find reference to Tragedy mask. This will cause problems later!!");
}
EnemyType val7 = __instance.currentLevel?.Enemies?.FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType).name == "MaskedPlayerEnemy"))?.enemyType ?? Object.FindAnyObjectByType<QuickMenuManager>()?.testAllEnemiesLevel?.Enemies?.FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity enemy) => ((Object)enemy.enemyType).name == "MaskedPlayerEnemy"))?.enemyType;
if ((Object)(object)val7 != (Object)null)
{
val7.isOutsideEnemy = false;
Plugin.Logger.LogDebug((object)"Masked: Subtract from indoor power, not outdoor power");
}
else
{
Plugin.Logger.LogWarning((object)"Failed to find reference to Masked enemy type. Could not apply power level fix");
}
}
[HarmonyPatch(typeof(StartOfRound), "Start")]
[HarmonyPostfix]
[HarmonyAfter(new string[] { "x753.More_Suits" })]
private static void StartOfRound_Post_Start(StartOfRound __instance)
{
suitIndices.Clear();
string[] array = Array.Empty<string>();
try
{
array = Plugin.configSuitWhitelist.Value.Split(',');
}
catch
{
array = "orange,green,hazard,pajama,purple,bee,bunny".Split(',');
}
bool flag = false;
for (int i = 0; i < __instance.unlockablesList.unlockables.Count; i++)
{
string[] array2 = array;
foreach (string text in array2)
{
if (!__instance.unlockablesList.unlockables[i].unlockableName.ToLower().StartsWith(text.ToLower()))
{
continue;
}
if (__instance.unlockablesList.unlockables[i].unlockableName == "Orange suit")
{
if (flag)
{
continue;
}
flag = true;
}
suitIndices.Add(i);
Plugin.Logger.LogDebug((object)("Random suit list: Added \"" + __instance.unlockablesList.unlockables[i].unlockableName + "\""));
}
}
}
private static void ConvertMaskToTragedy(Transform mask)
{
Transform val = mask.Find("Mesh");
if ((Object)(object)val != (Object)null && (Object)(object)TRAGEDY_MASK != (Object)null && (Object)(object)TRAGEDY_MAT != (Object)null)
{
((Component)val).GetComponent<MeshFilter>().mesh = TRAGEDY_MASK;
((Renderer)((Component)val).GetComponent<MeshRenderer>()).sharedMaterial = TRAGEDY_MAT;
Transform obj = val.Find("EyesFilled");
MeshFilter val2 = ((obj != null) ? ((Component)obj).GetComponent<MeshFilter>() : null);
if ((Object)(object)val2 != (Object)null && (Object)(object)TRAGEDY_EYES_FILLED != (Object)null)
{
val2.mesh = TRAGEDY_EYES_FILLED;
Transform obj2 = mask.Find("ComedyMaskLOD1");
MeshFilter val3 = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshFilter>() : null);
if ((Object)(object)val3 != (Object)null && (Object)(object)TRAGEDY_MASK_LOD != (Object)null)
{
val3.mesh = TRAGEDY_MASK_LOD;
((Renderer)((Component)val3).GetComponent<MeshRenderer>()).sharedMaterial = TRAGEDY_MAT;
Plugin.Logger.LogDebug((object)$"Mask {((Object)mask).GetInstanceID()}: All meshes replaced successfully");
}
else
{
Plugin.Logger.LogWarning((object)$"Mask {((Object)mask).GetInstanceID()}: Failed to replace eyes");
}
}
else
{
Plugin.Logger.LogWarning((object)$"Mask {((Object)mask).GetInstanceID()}: Failed to replace LOD");
}
}
else
{
Plugin.Logger.LogWarning((object)$"Mask {((Object)mask).GetInstanceID()}: Failed to replace mesh");
}
}
[HarmonyPatch(typeof(HauntedMaskItem), "MaskClampToHeadAnimationEvent")]
[HarmonyPostfix]
private static void HauntedMaskItem_Post_MaskClampToHeadAnimationEvent(HauntedMaskItem __instance)
{
if (__instance.maskTypeId == 5)
{
Plugin.Logger.LogDebug((object)$"Mask #{((Object)__instance).GetInstanceID()}: I am a Tragedy, change appearance of face mask");
ConvertMaskToTragedy(((Component)__instance.currentHeadMask).transform);
}
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
private static void MaskedPlayerEnemy_Post_Update(MaskedPlayerEnemy __instance)
{
if (__instance.maskFloodParticle.isEmitting && (Object)(object)((EnemyAI)__instance).inSpecialAnimationWithPlayer != (Object)null)
{
if ((Object)(object)((EnemyAI)__instance).inSpecialAnimationWithPlayer == (Object)(object)GameNetworkManager.Instance.localPlayerController && !HUDManager.Instance.HUDAnimator.GetBool("biohazardDamage"))
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Vomiting blood on local player, do HUD animation");
HUDManager.Instance.HUDAnimator.SetBool("biohazardDamage", true);
}
((EnemyAI)__instance).inSpecialAnimationWithPlayer.bodyBloodDecals[3].SetActive(true);
}
}
[HarmonyPatch("FinishKillAnimation")]
[HarmonyPrefix]
private static void MaskedPlayerEnemy_Pre_FinishKillAnimation(MaskedPlayerEnemy __instance)
{
if ((Object)(object)((EnemyAI)__instance).inSpecialAnimationWithPlayer == (Object)(object)GameNetworkManager.Instance.localPlayerController && HUDManager.Instance.HUDAnimator.GetBool("biohazardDamage"))
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Vomit animation interrupted during HUD animation");
if (__instance.maskFloodParticle.isEmitting)
{
__instance.maskFloodParticle.Stop();
}
HUDManager.Instance.HUDAnimator.SetBool("biohazardDamage", false);
HUDManager.Instance.HUDAnimator.SetTrigger("HealFromCritical");
}
}
[HarmonyPatch("KillEnemy")]
[HarmonyPostfix]
private static void MaskedPlayerEnemy_Post_KillEnemy(MaskedPlayerEnemy __instance, bool destroy)
{
if (!destroy)
{
Transform obj = ((Component)__instance).transform.Find("Misc/MapDot");
Animator val = ((obj != null) ? ((Component)obj).GetComponent<Animator>() : null);
if ((Object)(object)val != (Object)null)
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Stop animating radar dot");
((Behaviour)val).enabled = false;
}
RandomPeriodicAudioPlayer componentInChildren = ((Component)((Component)__instance).transform).GetComponentInChildren<RandomPeriodicAudioPlayer>();
if ((Object)(object)componentInChildren != (Object)null)
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Mask becomes silent");
((Behaviour)componentInChildren).enabled = false;
}
}
}
[HarmonyPatch("SetSuit")]
[HarmonyPostfix]
private static void MaskedPlayerEnemy_Post_SetSuit(MaskedPlayerEnemy __instance, int suitId)
{
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Expected O, but got Unknown
Transform val = __instance.animationContainer.Find("metarig/spine");
Transform val2 = val.Find("spine.001/spine.002/spine.003/spine.004");
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
return;
}
try
{
List<MeshRenderer> list = new List<MeshRenderer>(((EnemyAI)__instance).meshRenderers);
if (suitId < StartOfRound.Instance.unlockablesList.unlockables.Count)
{
Transform[] array = (Transform[])(object)new Transform[2] { val, val2 };
for (int i = 0; i < array.Length; i++)
{
foreach (Transform item4 in array[i])
{
Transform val3 = item4;
if (((Object)val3).name.Contains("Container(Clone)"))
{
MeshRenderer[] componentsInChildren = ((Component)val3).GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer item in componentsInChildren)
{
list.Remove(item);
}
Object.Destroy((Object)(object)((Component)val3).gameObject);
}
}
}
UnlockableItem val4 = StartOfRound.Instance.unlockablesList.unlockables[suitId];
if ((Object)(object)val4.headCostumeObject != (Object)null)
{
MeshRenderer[] componentsInChildren = Object.Instantiate<GameObject>(val4.headCostumeObject, val2.position, val2.rotation, val2).GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer item2 in componentsInChildren)
{
list.Add(item2);
}
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Equipped {val4.unlockableName} head");
}
if ((Object)(object)val4.lowerTorsoCostumeObject != (Object)null)
{
MeshRenderer[] componentsInChildren = Object.Instantiate<GameObject>(val4.lowerTorsoCostumeObject, val.position, val.rotation, val).GetComponentsInChildren<MeshRenderer>();
foreach (MeshRenderer item3 in componentsInChildren)
{
list.Add(item3);
}
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Equipped {val4.unlockableName} torso");
}
}
((EnemyAI)__instance).meshRenderers = list.ToArray();
}
catch (Exception arg)
{
Plugin.Logger.LogWarning((object)$"Encountered a non-fatal error while attaching costume pieces to mimic\n{arg}");
}
}
[HarmonyPatch("SetEnemyOutside")]
[HarmonyPostfix]
private static void MaskedPlayerEnemy_Post_SetEnemyOutside(MaskedPlayerEnemy __instance)
{
if ((Object)(object)__instance.mimickingPlayer == (Object)null || ((EnemyAI)__instance).timeSinceSpawn > 40f)
{
return;
}
Transform parent = __instance.maskTypes[0].transform.parent.parent;
Transform obj = parent.Find("BetaBadge");
Renderer val = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
if ((Object)(object)val != (Object)null)
{
val.enabled = ((Renderer)__instance.mimickingPlayer.playerBetaBadgeMesh).enabled;
Plugin.Logger.LogDebug((object)string.Format("Mimic #{0}: VIP {1}", ((Object)__instance).GetInstanceID(), val.enabled ? "enabled" : "disabled"));
}
Transform obj2 = parent.Find("LevelSticker");
MeshFilter val2 = ((obj2 != null) ? ((Component)obj2).GetComponent<MeshFilter>() : null);
if ((Object)(object)val2 != (Object)null)
{
val2.mesh = __instance.mimickingPlayer.playerBadgeMesh.mesh;
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Updated level sticker");
}
try
{
DecalProjector[] componentsInChildren = ((Component)((Component)__instance).transform).GetComponentsInChildren<DecalProjector>();
foreach (DecalProjector val3 in componentsInChildren)
{
GameObject[] bodyBloodDecals = __instance.mimickingPlayer.bodyBloodDecals;
foreach (GameObject val4 in bodyBloodDecals)
{
if (((Object)val3).name == ((Object)val4).name)
{
((Component)val3).gameObject.SetActive(val4.activeSelf);
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Enabled blood decal \"{((Object)val3).name}\"");
}
}
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)"Encountered a non-fatal error while enabling mimic blood");
Plugin.Logger.LogError((object)ex);
}
}
[HarmonyPatch("SetMaskType")]
[HarmonyPrefix]
private static bool MaskedPlayerEnemy_Post_SetMaskType(MaskedPlayerEnemy __instance, int maskType)
{
if (maskType == 5 && __instance.maskTypeIndex != 1)
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Should be Tragedy");
ConvertMaskToTragedy(__instance.maskTypes[0].transform);
RandomPeriodicAudioPlayer component = __instance.maskTypes[0].GetComponent<RandomPeriodicAudioPlayer>();
if ((Object)(object)component != (Object)null)
{
component.thisAudio.Stop();
if (TRAGEDY_RANDOM_CLIPS != null)
{
component.randomClips = TRAGEDY_RANDOM_CLIPS;
if (((NetworkBehaviour)component).IsServer)
{
component.lastIntervalTime = Time.realtimeSinceStartup + component.currentInterval - Time.fixedDeltaTime;
}
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Cries");
}
else
{
((Behaviour)component).enabled = false;
Plugin.Logger.LogWarning((object)"Crying audio is missing, there should be more information earlier in the log");
}
}
}
return false;
}
[HarmonyPatch("Start")]
[HarmonyPostfix]
private static void MaskedPlayerEnemy_Post_Start(MaskedPlayerEnemy __instance)
{
if (!RoundManager.Instance.SpawnedEnemies.Contains((EnemyAI)(object)__instance))
{
RoundManager.Instance.SpawnedEnemies.Add((EnemyAI)(object)__instance);
}
Transform[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Transform>();
foreach (Transform val in componentsInChildren)
{
if (((Component)val).CompareTag("Player"))
{
((Component)val).tag = "Enemy";
}
else if (((Component)val).CompareTag("PlayerBody"))
{
((Component)val).tag = "Untagged";
}
}
if (!((Object)(object)__instance.mimickingPlayer == (Object)null) || !(Time.realtimeSinceStartup - safeTimer > 10f))
{
return;
}
if (Plugin.configRandomSuits.Value)
{
int num = suitIndices[new Random(StartOfRound.Instance.randomMapSeed + (int)((NetworkBehaviour)__instance).NetworkObjectId).Next(suitIndices.Count)];
if (num != 0)
{
__instance.SetSuit(num);
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Equip \"{StartOfRound.Instance.unlockablesList.unlockables[num].unlockableName}\"");
}
}
else if (StartOfRound.Instance.isChallengeFile)
{
__instance.SetSuit(24);
}
if (Plugin.configTragedyChance.Value > 0f && (Plugin.configTragedyChance.Value >= 1f || new Random(StartOfRound.Instance.randomMapSeed * (int)((NetworkBehaviour)__instance).NetworkObjectId).NextDouble() < (double)Plugin.configTragedyChance.Value))
{
__instance.SetMaskType(5);
}
}
[HarmonyPatch("HitEnemy")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> MaskedPlayerEnemy_Trans_HitEnemy(IEnumerable<CodeInstruction> instructions)
{
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Expected O, but got Unknown
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Expected O, but got Unknown
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
MethodInfo methodInfo = AccessTools.Method(typeof(Random), "Range", new Type[2]
{
typeof(int),
typeof(int)
}, (Type[])null);
for (int i = 0; i < list.Count; i++)
{
if (list[i].opcode == OpCodes.Call && (MethodInfo)list[i].operand == methodInfo)
{
list.InsertRange(i - 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
{
new CodeInstruction(OpCodes.Ldarg_0, (object)null),
new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredPropertyGetter(typeof(NetworkBehaviour), "IsOwner")),
new CodeInstruction(OpCodes.Brfalse, list[i + 3].operand)
}));
Plugin.Logger.LogDebug((object)"Transpiler (Mimic stun): Roll 40% chance to sprint only once");
return list;
}
}
Plugin.Logger.LogError((object)"Mimic stun transpiler failed");
return instructions;
}
[HarmonyPatch(typeof(EnemyAI), "SubtractFromPowerLevel")]
[HarmonyPrefix]
private static void EnemyAI_Pre_SubtractFromPowerLevel(EnemyAI __instance)
{
if (!__instance.removedPowerLevel)
{
MaskedPlayerEnemy val = (MaskedPlayerEnemy)(object)((__instance is MaskedPlayerEnemy) ? __instance : null);
if (val != null && (Object)(object)val.mimickingPlayer != (Object)null)
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Was mimicking a player; won't subtract from power level");
__instance.removedPowerLevel = true;
}
}
}
[HarmonyPatch(typeof(EnemyAI), "EnableEnemyMesh")]
[HarmonyPrefix]
private static bool EnemyAI_Pre_EnableEnemyMesh(EnemyAI __instance, bool enable, bool overrideDoNotSet)
{
if (Plugin.DISABLE_ENEMY_MESH_PATCH)
{
return true;
}
int layer = (enable ? 19 : 23);
for (int i = 0; i < __instance.skinnedMeshRenderers.Length; i++)
{
if ((Object)(object)__instance.skinnedMeshRenderers[i] == (Object)null)
{
__instance.skinnedMeshRenderers = __instance.skinnedMeshRenderers.Where((SkinnedMeshRenderer skinnedMeshRenderer) => (Object)(object)skinnedMeshRenderer != (Object)null).ToArray();
Plugin.Logger.LogWarning((object)("Removed all missing Skinned Mesh Renderers from enemy \"" + ((Object)__instance).name + "\""));
break;
}
if (overrideDoNotSet || !((Component)__instance.skinnedMeshRenderers[i]).CompareTag("DoNotSet"))
{
((Component)__instance.skinnedMeshRenderers[i]).gameObject.layer = layer;
}
}
for (int j = 0; j < __instance.meshRenderers.Length; j++)
{
if ((Object)(object)__instance.meshRenderers[j] == (Object)null)
{
__instance.meshRenderers = __instance.meshRenderers.Where((MeshRenderer meshRenderer) => (Object)(object)meshRenderer != (Object)null).ToArray();
Plugin.Logger.LogWarning((object)("Removed all missing Mesh Renderers from enemy \"" + ((Object)__instance).name + "\""));
break;
}
if (overrideDoNotSet || !((Component)__instance.meshRenderers[j]).CompareTag("DoNotSet"))
{
((Component)__instance.meshRenderers[j]).gameObject.layer = layer;
}
}
return false;
}
[HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayer")]
[HarmonyPostfix]
private static void EntranceTeleport_Post_TeleportPlayer(EntranceTeleport __instance)
{
if (__instance.timeAtLastUse > localPlayerLastTeleported + 1f)
{
localPlayerLastTeleported = __instance.timeAtLastUse;
}
}
[HarmonyPatch("OnCollideWithPlayer")]
[HarmonyPrefix]
private static bool MaskedPlayerEnemy_Pre_OnCollideWithPlayer()
{
return Time.realtimeSinceStartup - localPlayerLastTeleported >= 1.75f;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyTranspiler]
private static IEnumerable<CodeInstruction> MaskedPlayerEnemy_Trans_DoAIInterval(IEnumerable<CodeInstruction> instructions)
{
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Expected O, but got Unknown
List<CodeInstruction> list = instructions.ToList();
FieldInfo fieldInfo = AccessTools.Field(typeof(MaskedPlayerEnemy), "elevatorScript");
for (int i = 1; i < list.Count; i++)
{
if (list[i].opcode == OpCodes.Stfld && (FieldInfo)list[i].operand == fieldInfo && list[i - 1].opcode == OpCodes.Call && list[i - 1].operand.ToString().Contains("FindObjectOfType"))
{
list[i - 1].operand = AccessTools.DeclaredPropertyGetter(typeof(RoundManager), "Instance");
list.Insert(i, new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(RoundManager), "currentMineshaftElevator")));
Plugin.Logger.LogDebug((object)"Transpiler (Mimic AI): Cache elevator script");
return list;
}
}
Plugin.Logger.LogError((object)"Mimic AI transpiler failed");
return instructions;
}
[HarmonyPatch("ChooseShipHidingSpot")]
[HarmonyPrefix]
private static bool MaskedPlayerEnemy_Pre_ChooseShipHidingSpot(MaskedPlayerEnemy __instance)
{
if (!Plugin.configPatchHidingBehavior.Value)
{
return true;
}
NewMaskedAI.HideOnShip(__instance);
return false;
}
[HarmonyPatch("DoAIInterval")]
[HarmonyPrefix]
private static bool MaskedPlayerEnemy_Pre_DoAIInterval(MaskedPlayerEnemy __instance)
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.configPatchRoamingBehavior.Value)
{
return true;
}
if (((EnemyAI)__instance).isEnemyDead || ((EnemyAI)__instance).currentBehaviourStateIndex != 0)
{
return true;
}
if (((EnemyAI)__instance).moveTowardsDestination)
{
((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
}
((EnemyAI)__instance).SyncPositionToClients();
NewMaskedAI.Roam(__instance);
if ((((EnemyAI)__instance).currentBehaviourStateIndex == 1 || ((EnemyAI)__instance).currentBehaviourStateIndex == 2) && (Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null && ((EnemyAI)__instance).PlayerIsTargetable(((EnemyAI)__instance).targetPlayer, false, false))
{
if (__instance.lostPlayerInChase)
{
((EnemyAI)__instance).movingTowardsTargetPlayer = false;
if (!__instance.searchForPlayers.inProgress)
{
((EnemyAI)__instance).StartSearch(((Component)__instance).transform.position, __instance.searchForPlayers);
}
}
else
{
if (__instance.searchForPlayers.inProgress)
{
((EnemyAI)__instance).StopSearch(__instance.searchForPlayers, true);
}
((EnemyAI)__instance).SetMovingTowardsTargetPlayer(((EnemyAI)__instance).targetPlayer);
}
}
return false;
}
[HarmonyPatch(typeof(RoundManager), "SpawnSyncedProps")]
[HarmonyPostfix]
private static void RoundManager_Post_SpawnSyncedProps()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
EntranceTeleport[] array = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0);
foreach (EntranceTeleport val in array)
{
if (val.entranceId == 0)
{
if (val.isEntranceToBuilding)
{
NewMaskedAI.mainEntrancePointOutside = val.entrancePoint.position;
}
else
{
NewMaskedAI.mainEntrancePoint = val.entrancePoint.position;
}
}
}
}
[HarmonyPatch(typeof(RoundManager), "GeneratedFloorPostProcessing")]
[HarmonyPostfix]
private static void RoundManager_Post_GeneratedFloorPostProcessing(RoundManager __instance)
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: 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_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: 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_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_012b: Unknown result type (might be due to invalid IL or missing references)
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0142: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0151: 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_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
//IL_017b: Unknown result type (might be due to invalid IL or missing references)
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_0183: Unknown result type (might be due to invalid IL or missing references)
if (__instance.currentDungeonType != 4)
{
return;
}
Transform val = __instance.dungeonGenerator.Root.transform.Find("MineshaftStartTile(Clone)");
if ((Object)(object)val == (Object)null)
{
Plugin.Logger.LogWarning((object)"Failed to find MineshaftStartTile, so can not compute start room bounds. This will cause problems later!!");
return;
}
Vector3[] array = (Vector3[])(object)new Vector3[8]
{
new Vector3(-16f, 41.37f, -4.3f),
new Vector3(14f, 41.37f, -4.3f),
new Vector3(-16f, 61.37f, -4.3f),
new Vector3(14f, 61.37f, -4.3f),
new Vector3(-16f, 41.37f, 10.7f),
new Vector3(14f, 41.37f, 10.7f),
new Vector3(-16f, 61.37f, 10.7f),
new Vector3(14f, 61.37f, 10.7f)
};
val.TransformPoints((Span<Vector3>)array);
Vector3 val2 = array[0];
Vector3 val3 = array[0];
for (int i = 1; i < array.Length; i++)
{
val2 = Vector3.Min(val2, array[i]);
val3 = Vector3.Max(val3, array[i]);
}
Bounds startRoomBounds = default(Bounds);
((Bounds)(ref startRoomBounds)).min = val2;
((Bounds)(ref startRoomBounds)).max = val3;
NewMaskedAI.startRoomBounds = startRoomBounds;
Plugin.Logger.LogDebug((object)"Calculated bounds for mineshaft elevator's start room");
}
[HarmonyPatch(typeof(HauntedMaskItem), "AttachClientRpc")]
[HarmonyPostfix]
private static void HauntedMaskItem_Post_AttachClientRpc()
{
safeTimer = Time.realtimeSinceStartup;
}
[HarmonyPatch("KillPlayerAnimationClientRpc")]
[HarmonyPostfix]
private static void MaskedPlayerEnemy_Post_KillPlayerAnimationClientRpc(MaskedPlayerEnemy __instance)
{
safeTimer = Time.realtimeSinceStartup;
}
}
[BepInPlugin("butterystancakes.lethalcompany.maskfixes", "Mask Fixes", "1.2.2")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private const string PLUGIN_GUID = "butterystancakes.lethalcompany.maskfixes";
private const string PLUGIN_NAME = "Mask Fixes";
private const string PLUGIN_VERSION = "1.2.2";
internal static ManualLogSource Logger;
private const string GUID_STARLANCER_AI_FIX = "AudioKnight.StarlancerAIFix";
internal static bool DISABLE_ENEMY_MESH_PATCH;
internal const string HARMONY_MORE_SUITS = "x753.More_Suits";
internal const string HARMONY_CLASSIC_SUIT_RESTORATION = "butterystancakes.lethalcompany.classicsuitrestoration";
internal const string VANILLA_SUITS = "orange,green,hazard,pajama,purple,bee,bunny";
internal static ConfigEntry<bool> configPatchHidingBehavior;
internal static ConfigEntry<bool> configPatchRoamingBehavior;
internal static ConfigEntry<bool> configRandomSuits;
internal static ConfigEntry<float> configTragedyChance;
internal static ConfigEntry<string> configSuitWhitelist;
private void Awake()
{
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Expected O, but got Unknown
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BaseUnityPlugin)this).Logger;
if (Chainloader.PluginInfos.ContainsKey("AudioKnight.StarlancerAIFix"))
{
DISABLE_ENEMY_MESH_PATCH = true;
Logger.LogInfo((object)"CROSS-COMPATIBILITY - EnableEnemyMesh patch will be disabled");
}
configPatchHidingBehavior = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Patch Hiding Behavior", true, "(Host only) Changes the behavior Masked use to hide aboard the ship. This means multiple Masked will hide aboard different spots on the ship, and reduces the likelihood they will get stuck pathing into each other.");
configPatchRoamingBehavior = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "Patch Roaming Behavior", true, "(Host only) Rewrites Masked roaming behavior to fix some bugs with the vanilla implementation. This will fix Masked entering/exiting the building constantly, or getting stuck on the mineshaft elevator.");
configRandomSuits = ((BaseUnityPlugin)this).Config.Bind<bool>("Bonus", "Random Suits", false, "(Client-side) Naturally spawning Masked will wear a random vanilla suit.");
configSuitWhitelist = ((BaseUnityPlugin)this).Config.Bind<string>("Bonus", "Suit Whitelist", "orange,green,hazard,pajama,purple,bee,bunny", "(Client-side) A comma-separated list of suits that natural Masked are permitted to wear. This is not case-sensitive, and will match strings from front-to-back. (Example: \"cLAss\" will find \"Classic suit\" successfully)");
configTragedyChance = ((BaseUnityPlugin)this).Config.Bind<float>("Bonus", "Tragedy Chance", 0f, new ConfigDescription("(Client-side) The chance that a natural Masked will wear a Tragedy mask instead of a Comedy. (0.0 = all Comedy, 1.0 = all Tragedy, 0.5 = 50/50)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
new Harmony("butterystancakes.lethalcompany.maskfixes").PatchAll();
Logger.LogInfo((object)"Mask Fixes v1.2.2 loaded");
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "MaskFixes";
public const string PLUGIN_NAME = "MaskFixes";
public const string PLUGIN_VERSION = "1.2.2";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
int ICollection.Count => _items.Length;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
object IList.this[int index]
{
get
{
return _items[index];
}
set
{
throw new NotSupportedException();
}
}
bool IList.IsFixedSize => true;
bool IList.IsReadOnly => true;
int IReadOnlyCollection<T>.Count => _items.Length;
T IReadOnlyList<T>.this[int index] => _items[index];
int ICollection<T>.Count => _items.Length;
bool ICollection<T>.IsReadOnly => true;
T IList<T>.this[int index]
{
get
{
return _items[index];
}
set
{
throw new NotSupportedException();
}
}
public <>z__ReadOnlyArray(T[] items)
{
_items = items;
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)_items).GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{
((ICollection)_items).CopyTo(array, index);
}
int IList.Add(object value)
{
throw new NotSupportedException();
}
void IList.Clear()
{
throw new NotSupportedException();
}
bool IList.Contains(object value)
{
return ((IList)_items).Contains(value);
}
int IList.IndexOf(object value)
{
return ((IList)_items).IndexOf(value);
}
void IList.Insert(int index, object value)
{
throw new NotSupportedException();
}
void IList.Remove(object value)
{
throw new NotSupportedException();
}
void IList.RemoveAt(int index)
{
throw new NotSupportedException();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return ((IEnumerable<T>)_items).GetEnumerator();
}
void ICollection<T>.Add(T item)
{
throw new NotSupportedException();
}
void ICollection<T>.Clear()
{
throw new NotSupportedException();
}
bool ICollection<T>.Contains(T item)
{
return ((ICollection<T>)_items).Contains(item);
}
void ICollection<T>.CopyTo(T[] array, int arrayIndex)
{
((ICollection<T>)_items).CopyTo(array, arrayIndex);
}
bool ICollection<T>.Remove(T item)
{
throw new NotSupportedException();
}
int IList<T>.IndexOf(T item)
{
return ((IList<T>)_items).IndexOf(item);
}
void IList<T>.Insert(int index, T item)
{
throw new NotSupportedException();
}
void IList<T>.RemoveAt(int index)
{
throw new NotSupportedException();
}
}