Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RobeStalker v1.0.0
RobeStalker.dll
Decompiled 14 hours agousing System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Timers; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using REPOLib.Modules; using UnityEngine; [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: AssemblyCompany("CrowOfJudgement")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+bd9378a5a8a2039d4368d8da0b57578c440295d6")] [assembly: AssemblyProduct("RobeStalker")] [assembly: AssemblyTitle("RobeStalker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 RobeStalker { public class RespawnTimer : Timer { public EnemyRobe TargetEnemy; public RespawnTimer(EnemyRobe instance) { TargetEnemy = instance; } } [BepInPlugin("CrowOfJudgement.RobeStalker", "RobeStalker", "1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class RobeStalker : BaseUnityPlugin { public static ConfigEntry<bool> AllBullyOne; public static ConfigEntry<bool> AddChosenEffect; public static ConfigEntry<float> EffectShakeStrength; public static ConfigEntry<float> EffectShakeDuration; public static ConfigEntry<int> StalkingProgressNeeded; public static ConfigEntry<int> StalkingProgressDifficulty; public static ConfigEntry<float> CameraProximityForSeeingRobe; public static ConfigEntry<bool> ReviveRobeOnStareBack; public static ConfigEntry<int> ReviveChanceForRobe; public static ConfigEntry<int> MaximumRevivePerRobe; public static ConfigEntry<bool> AggressiveRobe; public static ConfigEntry<float> MinimumReviveDistance; public static ConfigEntry<float> MaximumReviveDistance; public static PlayerAvatar? BullyTarget; private static ConcurrentDictionary<PlayerAvatar, int> m_StalkingProgress = new ConcurrentDictionary<PlayerAvatar, int>(); private static List<RespawnTimer> m_RespawnTimers = new List<RespawnTimer>(); private static NetworkedEvent? TargetIndicatorEvent; private static NetworkedEvent? FullyStalkedIndicatorEvent; private static NetworkedEvent? StalkedBackIndicatorEvent; private static EnemySetup robeEnemySetup = null; internal static RobeStalker Instance { get; private set; } = null; internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } public static ConcurrentDictionary<PlayerAvatar, int> StalkingProgressDictionary => m_StalkingProgress; public static List<RespawnTimer> RespawnTimers => m_RespawnTimers; public static NetworkedEvent? GetTargetIndicatorNetworkEvent() { return TargetIndicatorEvent; } public static NetworkedEvent? GetFullyStalkedIndicatorEvent() { return FullyStalkedIndicatorEvent; } public static NetworkedEvent? GetStalkedBackIndicatorEvent() { return StalkedBackIndicatorEvent; } public static bool IsNotInLevel() { return SemiFunc.RunIsLobby() || SemiFunc.RunIsLobbyMenu() || SemiFunc.IsMainMenu() || SemiFunc.IsSplashScreen(); } public static bool IsHost() { return SemiFunc.IsMasterClientOrSingleplayer(); } private void Awake() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; InitConfig(); Patch(); TargetIndicatorEvent = new NetworkedEvent("RobeTargetIndicator", (Action<EventData>)OnTargetIndicatorEvent); FullyStalkedIndicatorEvent = new NetworkedEvent("RobeTargetStalked", (Action<EventData>)OnTargetStalkedEvent); StalkedBackIndicatorEvent = new NetworkedEvent("RobeStalkedBack", (Action<EventData>)OnStalkedBackEvent); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { if (IsNotInLevel()) { if (!StalkingProgressDictionary.IsEmpty) { StalkingProgressDictionary.Clear(); } if (RespawnTimers.Count > 0) { RespawnTimers.ForEach(delegate(RespawnTimer x) { x.Stop(); }); RespawnTimers.Clear(); } } else if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)BullyTarget == (Object)null && AllBullyOne.Value) { List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list.Count == 1) { BullyTarget = list.First(); return; } int num = Random.RandomRangeInt(1, list.Count); BullyTarget = list[num - 1]; } } private void InitConfig() { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown AllBullyOne = ((BaseUnityPlugin)this).Config.Bind<bool>("Bully mode", "Enabled", false, "At the start of the map, one player will be targeted. All robes will bully this player. Host setting matters."); AggressiveRobe = ((BaseUnityPlugin)this).Config.Bind<bool>("Aggressive mode", "Enabled", false, "The robe will be more aggressive this way. Currently affects revive and puts her to a target state directly. Host setting matters."); AddChosenEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Target effect", "Enabled", true, "When a target is chosen, it will receive an effect. Local setting matters."); EffectShakeStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Effect strength", "Enabled", 30f, new ConfigDescription("Changes how strong the camera shakes during the target indicator effect. If the Target effect is disabled, this option has no effect. Local settings matter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); EffectShakeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Effect duration", "Enabled", 1f, new ConfigDescription("Changes how long the camera will shake during the target indicator effect. If the Target effect is disabled, this option has no effect. Local settings matter.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); StalkingProgressNeeded = ((BaseUnityPlugin)this).Config.Bind<int>("Stalking threshold", "Enabled", 30000, new ConfigDescription("Changes how fast the robe will stalk the player. Note that this triggers every Update-cycle, so keep the number high or it will be too fast. Host setting matters.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100000), Array.Empty<object>())); StalkingProgressDifficulty = ((BaseUnityPlugin)this).Config.Bind<int>("Stalking Difficulty", "Enabled", 200, new ConfigDescription("Reduces the amount of stalking threshold per level. Note that if the stalking threshold gets to 0 due to this, players will be stalked immediately. Host setting matters.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100000), Array.Empty<object>())); CameraProximityForSeeingRobe = ((BaseUnityPlugin)this).Config.Bind<float>("Camera direction", "Enabled", 10f, new ConfigDescription("how close the player camera must be to the robe. The higher the value, the easier it will be to spot her. Host setting matters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 90f), Array.Empty<object>())); ReviveRobeOnStareBack = ((BaseUnityPlugin)this).Config.Bind<bool>("Revive enable", "Enabled", false, "If enabled, there will be configurable chance for a spotted robe to respawn at a random location. Host setting matters."); ReviveChanceForRobe = ((BaseUnityPlugin)this).Config.Bind<int>("Revive Chance", "Enabled", 2, new ConfigDescription("Sets the 1 in x chance for the robe to respawn when being spotted. Default 2 means 50% chance for respawn. If Revive enable is disabled, this option has no effect. Host setting matters. Minimum 1 for always respawn (endless torture).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); MaximumRevivePerRobe = ((BaseUnityPlugin)this).Config.Bind<int>("Maximum Revives", "Enabled", 0, new ConfigDescription("Defines the maximum amount of revives per robe instance. This can be handy if you for example want to have 100% revive chance but not endlessly. 0 means no limit. Host setting matters.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); MinimumReviveDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Revive distance minimum", "Enabled", 30f, new ConfigDescription("Defines the minimum distance to a LevelPoint for respawning robe. Distance is measured to the last position before she got stared back. Keep a good amount between min and max, or else no valid spawn points will be found. Host setting matters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>())); MaximumReviveDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Revive distance maximum", "Enabled", 80f, new ConfigDescription("Defines the minimum distance to a LevelPoint for respawning robe. Distance is measured to the last position before she got stared back. Keep a good amount between min and max, or else no valid spawn points will be found. Host setting matters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 500f), Array.Empty<object>())); } public static void CreateNewRespawnTimer(EnemyRobe info) { RespawnTimer respawnTimer = new RespawnTimer(info); respawnTimer.Interval = 5000.0; respawnTimer.Elapsed += TimerTrigger; respawnTimer.Start(); RespawnTimers.Add(respawnTimer); } public static void TimerTrigger(object sender, ElapsedEventArgs e) { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) RespawnTimer respawnTimer = (RespawnTimer)sender; Logger.LogDebug((object)"RobeStalker::TimerTrigger: Enemy spawn timer started"); if (SemiFunc.RunIsLobby() || SemiFunc.RunIsLobbyMenu() || SemiFunc.IsMainMenu() || SemiFunc.IsSplashScreen()) { Logger.LogInfo((object)"RobeStalker::TimerTrigger: cannot run while not in game!"); respawnTimer.Stop(); RespawnTimers.Clear(); return; } EnemyRobe targetEnemy = respawnTimer.TargetEnemy; if ((Object)(object)targetEnemy != (Object)null) { Logger.LogDebug((object)"RobeStalker::TimerTrigger: Enemy spawn data found"); RobeStalkerController component = ((Component)targetEnemy).GetComponent<RobeStalkerController>(); if ((Object)(object)component == (Object)null) { Logger.LogWarning((object)"RobeStalker::TimerTrigger: No Component found on Robe"); return; } if (MaximumRevivePerRobe.Value != 0 && component.CurrentRevives >= MaximumRevivePerRobe.Value) { Logger.LogInfo((object)"RobeStalker::TimerTrigger: Maximum revive counter hit!"); return; } EnemyParent componentInParent = ((Component)targetEnemy.enemy).GetComponentInParent<EnemyParent>(); if ((Object)(object)componentInParent != (Object)null) { LevelPoint val = null; List<LevelPoint> list = SemiFunc.LevelPointGetWithinDistance(((Component)targetEnemy).transform.position, MinimumReviveDistance.Value, MaximumReviveDistance.Value); if (list.Count <= 0) { Logger.LogWarning((object)"RobeStalker::TimerTrigger: no position found!"); return; } foreach (LevelPoint item in list) { if (item.inStartRoom) { continue; } val = item; break; } if ((Object)(object)val != (Object)null) { Logger.LogDebug((object)"RobeStalker::TimerTrigger: Enemy spawned"); componentInParent.Spawn(); Logger.LogDebug((object)("RobeStalker::TimerTrigger: enemy teleported to " + ((object)((Component)val).transform.position/*cast due to .constrained prefix*/).ToString())); targetEnemy.enemy.EnemyTeleported(((Component)val).transform.position); component.CurrentRevives++; } else { Logger.LogWarning((object)"RobeStalker::TimerTrigger: no point to teleport found!"); } } else { Logger.LogWarning((object)"RobeStalker::TimerTrigger: Enemy parent not found"); } } else { Logger.LogWarning((object)"Enemy spawn not possible, Enemy data is null!"); } respawnTimer.Stop(); RespawnTimers.Remove(respawnTimer); } public void OnTargetIndicatorEvent(EventData photonEvent) { Logger.LogDebug((object)"Received OnTargetIndicatorEvent"); if (!IsNotInLevel() && photonEvent.CustomData is object[] array && array.Length >= 3) { int robeID = (int)array[0]; int playerID = (int)array[1]; bool fullyStalked = (bool)array[2]; Logger.LogDebug((object)"Triggered HandleTriggerIndicatorEvent"); HandleTriggerIndicatorEvent(robeID, playerID, fullyStalked); } } public void OnTargetStalkedEvent(EventData photonEvent) { Logger.LogDebug((object)"Received OnTargetIndicatorEvent"); if (!IsNotInLevel() && photonEvent.CustomData is object[] array && array.Length >= 1) { int robeID = (int)array[0]; Logger.LogDebug((object)"Triggered HandleTriggerIndicatorEvent"); HandleTargetStalkedEvent(robeID); } } public void OnStalkedBackEvent(EventData photonEvent) { Logger.LogDebug((object)"Received OnTargetIndicatorEvent"); if (!IsNotInLevel() && photonEvent.CustomData is object[] array && array.Length >= 1) { int robeID = (int)array[0]; Logger.LogDebug((object)"Triggered HandleTriggerIndicatorEvent"); HandleStalkedBackEvent(robeID); } } private void HandleTriggerIndicatorEvent(int robeID, int playerID, bool FullyStalked) { PhotonView val = PhotonView.Find(robeID); PlayerAvatar val2 = SemiFunc.PlayerAvatarGetFromPhotonID(playerID); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { Logger.LogDebug((object)"HandleTriggerIndicatorEvent No robe or no Player"); return; } RobeStalkerController component = ((Component)val).GetComponent<RobeStalkerController>(); if ((Object)(object)component == (Object)null) { Logger.LogDebug((object)"HandleTriggerIndicatorEvent No Component found on Robe"); return; } component.PlayerTarget = val2; component.TargetFullyStalked = FullyStalked; if ((Object)(object)val2 == (Object)(object)SemiFunc.PlayerAvatarLocal()) { Logger.LogDebug((object)"HandleTriggerIndicatorEvent Player matches local player"); component.PlayHuntedIndicator(); } else { Logger.LogDebug((object)"HandleTriggerIndicatorEvent Player does not match local player"); } } private void HandleTargetStalkedEvent(int robeID) { PhotonView val = PhotonView.Find(robeID); if ((Object)(object)val == (Object)null) { Logger.LogDebug((object)"HandleTargetStalkedEvent No robe"); return; } RobeStalkerController component = ((Component)val).GetComponent<RobeStalkerController>(); if ((Object)(object)component == (Object)null) { Logger.LogDebug((object)"HandleTargetStalkedEvent No Component found on Robe"); } else { component.TargetStalked(); } } private void HandleStalkedBackEvent(int robeID) { PhotonView val = PhotonView.Find(robeID); if ((Object)(object)val == (Object)null) { Logger.LogDebug((object)"HandleStalkedBackEvent No robe or no Player"); return; } RobeStalkerController component = ((Component)val).GetComponent<RobeStalkerController>(); if ((Object)(object)component == (Object)null) { Logger.LogDebug((object)"HandleStalkedBackEvent No Component found on Robe"); } else { component.TargetStalkedBackAndBroadcast(); } } } public class RobeStalkerController : MonoBehaviour { private static ManualLogSource mls = RobeStalker.Logger; private EnemyRobe? m_RobeInstance = null; private PlayerAvatar? m_PlayerTarget; private int m_CurrentRevives = 0; private bool m_IsStalking = false; private bool m_IsBeingLookedAt = false; private bool m_TargetFullyStalked = false; private bool m_IsFleeing; public EnemyRobe? RobeInstance { get { if ((Object)(object)m_RobeInstance == (Object)null) { m_RobeInstance = ((Component)this).GetComponent<EnemyRobe>(); } return m_RobeInstance; } } public PlayerAvatar? PlayerTarget { get { return m_PlayerTarget; } set { m_PlayerTarget = value; if ((Object)(object)RobeInstance != (Object)null) { RobeInstance.targetPlayer = m_PlayerTarget; } } } public int CurrentRevives { get { return m_CurrentRevives; } set { m_CurrentRevives = value; } } public bool IsStalking { get { return m_IsStalking; } set { m_IsStalking = value; } } public bool IsBeingLookedAt { get { return m_IsBeingLookedAt; } set { m_IsBeingLookedAt = value; } } public bool TargetFullyStalked { get { return m_TargetFullyStalked; } set { m_TargetFullyStalked = value; } } public bool IsFleeing { get { return m_IsFleeing; } set { m_IsFleeing = value; } } public PlayerAvatar FindTargetAndBroadcast() { //IL_01b1: Unknown result type (might be due to invalid IL or missing references) List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); PlayerAvatar val; if ((Object)(object)RobeStalker.BullyTarget != (Object)null) { val = RobeStalker.BullyTarget; } else if (list.Count == 1) { val = list.First(); } else { int num = Random.RandomRangeInt(1, list.Count); val = list[num - 1]; } int value = 0; bool flag = RobeStalker.StalkingProgressDictionary.TryGetValue(val, out value); int num2 = RunManager.instance.levelsCompleted * RobeStalker.StalkingProgressDifficulty.Value; if (value >= RobeStalker.StalkingProgressNeeded.Value - num2) { TargetFullyStalked = true; } PlayerTarget = val; mls.LogDebug((object)("RobeStalkerPatch: Target player " + val.playerName)); if (SemiFunc.IsMasterClientOrSingleplayer()) { if ((Object)(object)val == (Object)(object)SemiFunc.PlayerAvatarLocal()) { mls.LogDebug((object)"RobeStalkerPatch: Player is similar to local player!"); PlayHuntedIndicator(); } if ((Object)(object)RobeInstance.photonView != (Object)null && (Object)(object)val.photonView != (Object)null && SemiFunc.IsMultiplayer()) { mls.LogDebug((object)"RobeStalkerPatch: Trigger networking event"); NetworkedEvent targetIndicatorNetworkEvent = RobeStalker.GetTargetIndicatorNetworkEvent(); if (targetIndicatorNetworkEvent != null) { mls.LogDebug((object)"IsMasterClientOrSingleplayer Curevent is not null, will raise."); if (targetIndicatorNetworkEvent != null) { targetIndicatorNetworkEvent.RaiseEvent((object)new object[3] { RobeInstance.photonView.ViewID, val.photonView.ViewID, TargetFullyStalked }, NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } } } } return val; } public void TargetStalked(bool broadcast = false) { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) TargetFullyStalked = true; EnemyRobe? robeInstance = RobeInstance; if (robeInstance != null) { robeInstance.UpdateState((State)10); } EnemyRobe? robeInstance2 = RobeInstance; if (robeInstance2 != null) { robeInstance2.OnVision(); } if (!broadcast || !SemiFunc.IsMasterClientOrSingleplayer() || !((Object)(object)RobeInstance?.photonView != (Object)null) || !SemiFunc.IsMultiplayer()) { return; } mls.LogDebug((object)"TargetStalked: broadcasting!"); NetworkedEvent fullyStalkedIndicatorEvent = RobeStalker.GetFullyStalkedIndicatorEvent(); if (fullyStalkedIndicatorEvent != null) { mls.LogWarning((object)"TargetStalkedAndBroadcast Curevent is not null, will raise."); if (fullyStalkedIndicatorEvent != null) { fullyStalkedIndicatorEvent.RaiseEvent((object)new object[1] { RobeInstance.photonView.ViewID }, NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } } } public void TargetStalkedBackAndBroadcast(bool broadcast = false) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) IsFleeing = true; EnemyRobe? robeInstance = RobeInstance; if (robeInstance != null) { robeInstance.UpdateState((State)14); } if (!broadcast || !SemiFunc.IsMasterClientOrSingleplayer() || !((Object)(object)RobeInstance?.photonView != (Object)null) || !SemiFunc.IsMultiplayer()) { return; } NetworkedEvent stalkedBackIndicatorEvent = RobeStalker.GetStalkedBackIndicatorEvent(); if (stalkedBackIndicatorEvent != null) { mls.LogDebug((object)"TargetStalkedBackAndBroadcast Curevent is not null, will raise."); if (stalkedBackIndicatorEvent != null) { stalkedBackIndicatorEvent.RaiseEvent((object)new object[1] { RobeInstance.photonView.ViewID }, NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } } } public void PlayHuntedIndicator() { mls.LogDebug((object)"RobeStalker::PlayHuntedIndicator: start"); PlayerAvatar val = SemiFunc.PlayerAvatarLocal(); if ((Object)(object)val != (Object)null && (Object)(object)RobeInstance != (Object)null && RobeStalker.AddChosenEffect.Value) { mls.LogDebug((object)"RobeStalker::PlayHuntedIndicator: doing it now!"); SemiFunc.CameraShake(RobeStalker.EffectShakeStrength.Value, RobeStalker.EffectShakeDuration.Value); Sound sfxIdleBreak = RobeInstance.robeAnim.sfxIdleBreak; sfxIdleBreak.ReverbMix = 1.1f; sfxIdleBreak.Play(((Component)val).transform, 1f, 1f, 1f, 1f); RobeInstance.targetPlayer = val; } mls.LogDebug((object)"RobeStalker::PlayHuntedIndicator: end"); } } [HarmonyPatch(typeof(EnemyRobe))] internal static class RobeStalkerPatch { private static ManualLogSource mls = RobeStalker.Logger; [HarmonyPrefix] [HarmonyPatch("Awake")] private static bool AwakePatch(EnemyRobe __instance) { mls.LogDebug((object)"RobeStalkerPatch: Awake Postfix"); if (RobeStalker.IsNotInLevel()) { return true; } if ((Object)(object)((Component)__instance).GetComponent<RobeStalkerController>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<RobeStalkerController>(); } return true; } [HarmonyPostfix] [HarmonyPatch("StateSeekPlayer")] private static void StateSeekPlayerPatch(EnemyRobe __instance) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) mls.LogDebug((object)"RobeStalkerPatch: StateSeekPlayerPatch Postfix"); if (!RobeStalker.IsNotInLevel()) { ((Component)__instance).transform.LookAt(((Component)__instance.targetPlayer).transform.position); } } [HarmonyPostfix] [HarmonyPatch("StateRoam")] private static void StateRoamPatch(EnemyRobe __instance) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) mls.LogDebug((object)"RobeStalkerPatch: StateRoamPatch Postfix"); if (!RobeStalker.IsNotInLevel()) { ((Component)__instance).transform.LookAt(((Component)__instance.targetPlayer).transform.position); } } [HarmonyPostfix] [HarmonyPatch("StateSpawn")] private static void StateSpawnPatch(EnemyRobe __instance) { mls.LogDebug((object)"RobeStalkerPatch: StateSpawnPatch Postfix"); if (!SemiFunc.IsMasterClientOrSingleplayer() || RobeStalker.IsNotInLevel()) { return; } RobeStalkerController robeStalkerController = ((__instance != null) ? ((Component)__instance).GetComponent<RobeStalkerController>() : null); if ((Object)(object)robeStalkerController == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: StateSpawnPatch kein RobeStalkerController!?"); return; } if ((Object)(object)robeStalkerController.PlayerTarget == (Object)null) { PlayerAvatar val = robeStalkerController.FindTargetAndBroadcast(); if ((Object)(object)val == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: StateSpawnPatch kein Playertarget auffindbar!"); } } if (robeStalkerController.IsFleeing) { robeStalkerController.IsFleeing = false; if (RobeStalker.AggressiveRobe.Value) { __instance.UpdateState((State)4); } else { __instance.UpdateState((State)9); } } } [HarmonyPostfix] [HarmonyPatch("StateDespawn")] private static void StateDespawnPatch(EnemyRobe __instance) { mls.LogDebug((object)"RobeStalkerPatch: StateDespawnPatch Postfix"); if (SemiFunc.IsMasterClientOrSingleplayer() && !RobeStalker.IsNotInLevel()) { RobeStalkerController robeStalkerController = ((__instance != null) ? ((Component)__instance).GetComponent<RobeStalkerController>() : null); if ((Object)(object)robeStalkerController == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: StateDespawnPatch kein RobeStalkerController!?"); } else if ((Object)(object)robeStalkerController.PlayerTarget != (Object)null) { robeStalkerController.PlayerTarget = null; } } } [HarmonyPrefix] [HarmonyPatch("Update")] private unsafe static bool UpdatePatch(EnemyRobe __instance) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_05ed: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Invalid comparison between Unknown and I4 //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_0604: Invalid comparison between Unknown and I4 //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03f7: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0436: Unknown result type (might be due to invalid IL or missing references) //IL_0438: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: 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_0325: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Prefix"); if (!RobeStalker.IsNotInLevel()) { RobeStalkerController component = ((Component)__instance).GetComponent<RobeStalkerController>(); if ((Object)(object)component == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: UpdatePatch kein RobeStalkerController!?"); return true; } PlayerAvatar playerTarget = component.PlayerTarget; if ((Object)(object)playerTarget == (Object)null) { mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch kein TargetPlayer"); return true; } if ((Object)(object)__instance.targetPlayer != (Object)(object)playerTarget) { __instance.targetPlayer = playerTarget; } if (component.TargetFullyStalked) { ((Component)__instance).transform.LookAt(((Component)__instance.targetPlayer).transform.position); } if (SemiFunc.IsMasterClientOrSingleplayer()) { int value = 0; if (!RobeStalker.StalkingProgressDictionary.TryGetValue(__instance.targetPlayer, out value)) { RobeStalker.StalkingProgressDictionary[__instance.targetPlayer] = 0; } mls.LogDebug((object)("RobeStalkerPatch: UpdatePatch Robe hat State " + ((object)Unsafe.As<State, State>(ref __instance.currentState)/*cast due to .constrained prefix*/).ToString())); if (!component.IsFleeing) { Vector3 position = ((Component)__instance).transform.position; int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()); Vector3 position2 = ((Component)__instance.targetPlayer).transform.position; Vector3 val = position2 - position; float num2 = Vector3.Angle(((Component)__instance).transform.forward, val); mls.LogDebug((object)("RobeStalkerPatch: UpdatePatch Robe schaut auf Spieler? Magnitude passt! " + num2)); if (num2 <= 30f) { Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * 3f; Vector3 val3 = ((Component)__instance.targetPlayer).transform.position + Vector3.up * 0.5f; mls.LogDebug((object)("Linecast Robe->Player: " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString() + " -> " + ((object)(*(Vector3*)(&val3))/*cast due to .constrained prefix*/).ToString())); RaycastHit val4 = default(RaycastHit); if (Physics.Linecast(val2, val3, ref val4, num, (QueryTriggerInteraction)0)) { if (((Object)((RaycastHit)(ref val4)).transform.root).name == "Player") { mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Robe schaut auf Spieler!"); component.IsStalking = true; } else { mls.LogDebug((object)("RobeStalkerPatch: UpdatePatch Robe sieht keinen Spieler: " + ((Object)((RaycastHit)(ref val4)).collider).name + "|" + ((Object)((RaycastHit)(ref val4)).transform.root).name + "|" + ((Object)((Component)((RaycastHit)(ref val4)).collider).transform.parent).name + ":" + ((object)((RaycastHit)(ref val4)).point/*cast due to .constrained prefix*/).ToString() + "|" + ((object)((RaycastHit)(ref val4)).transform.position/*cast due to .constrained prefix*/).ToString())); component.IsStalking = false; } } else { mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Robe schaut auf Spieler!"); component.IsStalking = true; } } else { mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Robe Spieler nicht in FOV"); component.IsStalking = false; } if (!component.TargetFullyStalked) { int num3 = LayerMask.op_Implicit(SemiFunc.LayerMaskGetPlayersAndPhysObjects()); Transform visionTransform = playerTarget.PlayerVisionTarget.VisionTransform; Vector3 val5 = ((Component)__instance).transform.position + Vector3.up * 3f; Vector3 val6 = val5 - visionTransform.position; ((Component)__instance).transform.LookAt(visionTransform); float num4 = Vector3.Angle(visionTransform.forward, val6); ManualLogSource obj = mls; string[] obj2 = new string[7] { "Linecast Player->Robe: ", ((object)visionTransform.position/*cast due to .constrained prefix*/).ToString(), " -> ", null, null, null, null }; Vector3 val7 = val5; obj2[3] = ((object)(*(Vector3*)(&val7))/*cast due to .constrained prefix*/).ToString(); obj2[4] = " (angle:"; obj2[5] = num4.ToString(); obj2[6] = ")"; obj.LogDebug((object)string.Concat(obj2)); RaycastHit val8 = default(RaycastHit); if (num4 <= RobeStalker.CameraProximityForSeeingRobe.Value && !Physics.Linecast(visionTransform.position, val5, ref val8, num3, (QueryTriggerInteraction)1)) { mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Spieler schaut auf Robe!"); component.IsBeingLookedAt = true; } else { mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Spieler sieht keine Robe."); } if (component.IsStalking) { value += 10; RobeStalker.StalkingProgressDictionary[playerTarget] = value; if (value >= RobeStalker.StalkingProgressNeeded.Value) { component.TargetStalked(broadcast: true); } } if (component.IsStalking && component.IsBeingLookedAt && !component.TargetFullyStalked) { component.TargetStalkedBackAndBroadcast(broadcast: true); if (RobeStalker.ReviveRobeOnStareBack.Value) { if (RobeStalker.MaximumRevivePerRobe.Value != 0 && component.CurrentRevives >= RobeStalker.MaximumRevivePerRobe.Value) { mls.LogInfo((object)"RobeStalker::TimerTrigger: Maximum revive counter hit!"); } else if (Random.RandomRangeInt(1, RobeStalker.ReviveChanceForRobe.Value) == 1) { mls.LogInfo((object)"RobeStalkerPatch::StateDespawnPatch: Enemy spawn timer created"); RobeStalker.CreateNewRespawnTimer(__instance); } } mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Robe Flucht!"); return false; } } else { component.IsStalking = false; component.IsBeingLookedAt = false; } } else if ((int)__instance.currentState > 0) { if ((int)__instance.currentState != 14) { __instance.UpdateState((State)14); } component.IsBeingLookedAt = false; component.IsStalking = false; mls.LogDebug((object)"RobeStalkerPatch: UpdatePatch Robe ist am flüchten!"); } return true; } return true; } return true; } [HarmonyPrefix] [HarmonyPatch("StateTargetPlayer")] private static bool StateTargetPlayerPatch(EnemyRobe __instance) { if (RobeStalker.IsNotInLevel()) { return true; } RobeStalkerController robeStalkerController = ((__instance != null) ? ((Component)__instance).GetComponent<RobeStalkerController>() : null); if ((Object)(object)robeStalkerController == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: StateTargetPlayerPatch Kein Controller!?"); return true; } if (robeStalkerController.TargetFullyStalked) { mls.LogDebug((object)"RobeStalkerPatch: StateTargetPlayerPatch Can attack!!"); return true; } mls.LogDebug((object)"RobeStalkerPatch: StateTargetPlayerPatch Cannot attack!!"); return false; } [HarmonyPrefix] [HarmonyPatch("MoveTowardPlayer")] private static bool MoveTowardPlayerPatch(EnemyRobe __instance) { //IL_00ac: 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_00d9: Unknown result type (might be due to invalid IL or missing references) if (RobeStalker.IsNotInLevel()) { return true; } mls.LogDebug((object)"RobeStalkerPatch: MoveTowardPlayerPatch Prefix"); if ((Object)(object)__instance == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: MoveTowardPlayerPatch keine Instance!?"); return true; } RobeStalkerController robeStalkerController = ((__instance != null) ? ((Component)__instance).GetComponent<RobeStalkerController>() : null); if ((Object)(object)robeStalkerController == (Object)null) { mls.LogWarning((object)"RobeStalkerPatch: MoveTowardPlayerPatch kein RobeStalkerController!?"); return true; } if (robeStalkerController.TargetFullyStalked) { mls.LogDebug((object)"RobeStalkerPatch: MoveTowardPlayer Can attack now!!"); return true; } mls.LogDebug((object)"RobeStalkerPatch: MoveTowardPlayer Cannot attack yet!! KEEP STALKING ROBE!"); ((Component)__instance).transform.forward = Vector3.zero; ((Component)__instance).transform.right = Vector3.zero; ((Component)__instance).transform.LookAt(((Component)__instance.targetPlayer).transform.position); return false; } } }