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 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.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4bdf4eb733b840980e2b939b9f1464e24714a275")]
[assembly: AssemblyProduct("MaskFixes")]
[assembly: AssemblyTitle("MaskFixes")]
[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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace MaskFixes
{
[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 LayerMask hideLayers = LayerMask.op_Implicit(LayerMask.NameToLayer("Default") | LayerMask.NameToLayer("Room") | LayerMask.NameToLayer("Colliders") | LayerMask.NameToLayer("PlaceableShipObject") | LayerMask.NameToLayer("DecalStickableSurface"));
[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");
}
}
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);
if (TRAGEDY_RANDOM_CLIPS != null)
{
RandomPeriodicAudioPlayer component = __instance.maskTypes[0].GetComponent<RandomPeriodicAudioPlayer>();
if ((Object)(object)component != (Object)null)
{
component.randomClips = TRAGEDY_RANDOM_CLIPS;
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Cries");
}
}
else
{
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);
}
}
[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)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_018f: Unknown result type (might be due to invalid IL or missing references)
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_0073: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.configPatchHidingBehavior.Value)
{
return true;
}
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)__instance).SetDestinationToPosition(StartOfRound.Instance.insideShipPositions[i].position, true))
{
continue;
}
__instance.shipHidingSpot = ((EnemyAI)__instance).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)__instance != (Object)(object)val && ((EnemyAI)val).currentBehaviourStateIndex == 2 && Vector3.Distance(__instance.shipHidingSpot, val.shipHidingSpot) < 1.75f)
{
flag = false;
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Can't choose hiding spot #{i}, already claimed by mimic #{((Object)val).GetInstanceID()}");
break;
}
}
}
if (flag)
{
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Claimed hiding spot #{i} at coords {__instance.shipHidingSpot}");
return false;
}
}
__instance.shipHidingSpot = StartOfRound.Instance.insideShipPositions[Random.Range(0, StartOfRound.Instance.insideShipPositions.Length)].position;
Plugin.Logger.LogDebug((object)$"Mimic #{((Object)__instance).GetInstanceID()}: Fall back to position at coords {__instance.shipHidingSpot}");
return false;
}
}
[BepInPlugin("butterystancakes.lethalcompany.maskfixes", "Mask Fixes", "1.0.0")]
[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.0.0";
internal static ManualLogSource Logger;
private const string GUID_STARLANCER_AI_FIX = "AudioKnight.StarlancerAIFix";
internal static bool DISABLE_ENEMY_MESH_PATCH;
internal static ConfigEntry<bool> configPatchHidingBehavior;
private void Awake()
{
//IL_0056: 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.");
new Harmony("butterystancakes.lethalcompany.maskfixes").PatchAll();
Logger.LogInfo((object)"Mask Fixes v1.0.0 loaded");
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "MaskFixes";
public const string PLUGIN_NAME = "MaskFixes";
public const string PLUGIN_VERSION = "1.0.0";
}
}
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();
}
}