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 BrutalCompanyAdditions v2.1.1
BepInEx/plugins/Sculas.BrutalCompanyAdditions.dll
Decompiled 2 years agousing 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.Configuration; using BepInEx.Logging; using BrutalCompanyAdditions.Events; using BrutalCompanyAdditions.Objects; using BrutalCompanyAdditions.Patches; using BrutalCompanyPlus; using BrutalCompanyPlus.BCP; using GameNetcodeStuff; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using MonoMod.Utils; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Sculas.BrutalCompanyAdditions")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Adds more events to Brutal Company!")] [assembly: AssemblyFileVersion("2.1.1.0")] [assembly: AssemblyInformationalVersion("2.1.1")] [assembly: AssemblyProduct("BrutalCompanyAdditions")] [assembly: AssemblyTitle("Sculas.BrutalCompanyAdditions")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.1.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] internal class <Module> { static <Module>() { NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<CurrentNetEvent>(); NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<CurrentNetEvent>(); } } 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 BrutalCompanyAdditions { public static class EventRegistry { public static readonly List<IEvent> Events = new List<IEvent> { new BlingBling(), new TheVault(), new MovingTurrets() }; private static readonly List<EventEnum> OriginalEvents = Plugin.eventWeightEntries.Where(delegate(KeyValuePair<EventEnum, ConfigEntry<int>> kvp) { KeyValuePair<EventEnum, ConfigEntry<int>> keyValuePair2 = kvp; return keyValuePair2.Value.Value > 0; }).Select(delegate(KeyValuePair<EventEnum, ConfigEntry<int>> kvp) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) KeyValuePair<EventEnum, ConfigEntry<int>> keyValuePair = kvp; return keyValuePair.Key; }).ToList(); public static readonly Dictionary<string, EventEnum> AllEvents = new Dictionary<string, EventEnum>(); private static readonly int OriginalEventCount = Plugin.eventWeightEntries.Count; public static List<EventEnum> SelectableEvents; public static bool IsCustomEvent(EventEnum EventId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 return (int)EventId >= OriginalEventCount; } public static IEvent GetEvent(EventEnum EventId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected I4, but got Unknown return Events[EventId - OriginalEventCount]; } public static IEvent GetEventByType<T>() where T : IEvent { return Events.Find((IEvent Event) => Event.GetType() == typeof(T)); } private static int GetEventId(IEvent Event) { return OriginalEventCount + Events.IndexOf(Event); } public static string GetEventName(EventEnum EventId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!IsCustomEvent(EventId)) { return ((object)(EventEnum)(ref EventId)).ToString(); } return GetEvent(EventId).Name; } public static void Initialize() { List<EventEnum> second = (from kvp in PluginConfig.EventConfig.Where(delegate(KeyValuePair<string, ConfigEntry<bool>> kvp) { KeyValuePair<string, ConfigEntry<bool>> keyValuePair2 = kvp; return keyValuePair2.Value.Value; }) select GetEventId(Events.Find(delegate(IEvent Event) { string name = Event.Name; KeyValuePair<string, ConfigEntry<bool>> keyValuePair = kvp; return name == keyValuePair.Key; }))).Cast<EventEnum>().ToList(); List<EventEnum> first = new List<EventEnum>(); IEnumerable<EventEnum> second2; if (!PluginConfig.CustomOnly.Value) { IEnumerable<EventEnum> originalEvents = OriginalEvents; second2 = originalEvents; } else { IEnumerable<EventEnum> originalEvents = (IEnumerable<EventEnum>)(object)new EventEnum[0]; second2 = originalEvents; } SelectableEvents = first.Concat(second2).Concat(second).ToList(); Extensions.AddRange<string, EventEnum>(AllEvents, Plugin.eventWeightEntries.ToDictionary(delegate(KeyValuePair<EventEnum, ConfigEntry<int>> Event) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) EventEnum key = Event.Key; return ((object)(EventEnum)(ref key)).ToString(); }, (KeyValuePair<EventEnum, ConfigEntry<int>> Event) => Event.Key)); Extensions.AddRange<string, EventEnum>(AllEvents, Events.ToDictionary((IEvent Event) => Event.Name, (IEvent Event) => (EventEnum)GetEventId(Event))); } public static bool IsActive(this IEvent Event) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 return (int)Utils.LastEvent == GetEventId(Event); } } [BepInPlugin("Sculas.BrutalCompanyAdditions", "BrutalCompanyAdditions", "2.1.1")] [BepInProcess("Lethal Company.exe")] public class Plugin : BaseUnityPlugin { private static bool _loaded; public static ManualLogSource Logger; public static GameObject BCNetworkManagerPrefab; private void Awake() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; PluginConfig.Bind(this); EventRegistry.Initialize(); InitializeNetcode(); InitializeBCNetworkManager(); Harmony val = new Harmony("Sculas.BrutalCompanyAdditions"); val.PatchAll(typeof(BCPatches)); val.PatchAll(typeof(AIPatches)); val.PatchAll(typeof(TerminalPatches)); Logger.LogWarning((object)"I'm alive! Time to rule the world >:]"); } private void Start() { InitializeBCManager(); } private void OnDestroy() { InitializeBCManager(); } private static void InitializeBCManager() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown if (!_loaded) { Logger.LogWarning((object)"Initializing BCManager..."); Object.DontDestroyOnLoad((Object)new GameObject("Sculas.BrutalCompanyAdditions", new Type[1] { typeof(BCManager) })); _loaded = true; } } private static void InitializeBCNetworkManager() { Logger.LogWarning((object)"Initializing BCNetworkManager..."); AssetBundle val = AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("BrutalCompanyAdditions.Assets.brutalcompanyadditions")); BCNetworkManagerPrefab = val.LoadAsset<GameObject>("Assets/BCNetworkManager.prefab"); BCNetworkManagerPrefab.AddComponent<BCNetworkManager>(); val.Unload(false); } private static void InitializeNetcode() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); foreach (Type type in types) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (!customAttributes.IsEmpty()) { Logger.LogWarning((object)("Initializing RPCs for " + type.Name + "...")); methodInfo.Invoke(null, null); } } } } } public static class PluginConfig { public static ConfigEntry<bool> CustomOnly { get; private set; } public static Dictionary<string, ConfigEntry<bool>> EventConfig { get; } = new Dictionary<string, ConfigEntry<bool>>(); public static ConfigEntry<int> TurretDamage { get; private set; } public static ConfigEntry<bool> DebugAI { get; private set; } public static ConfigEntry<bool> DebugAILogging { get; private set; } public static void Bind(Plugin Plugin) { CustomOnly = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("General", "CustomOnly", false, "Whether to only use custom events or not."); foreach (IEvent @event in EventRegistry.Events) { EventConfig[@event.Name] = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("Events", @event.Name, true, @event.Description + " (default: enabled)"); bool value = EventConfig[@event.Name].Value; Plugin.Logger.LogInfo((object)("Event " + @event.Name + " is " + (value ? "enabled" : "disabled") + ".")); } TurretDamage = ((BaseUnityPlugin)Plugin).Config.Bind<int>("Difficulty", "TurretDamage", 25, "Amount of damage a turret does to a player during the MovingTurrets event (vanilla: 50)"); DebugAI = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("Advanced", "DebugAI", false, "Whether to show debug text above custom enemies or not (host only, can cause mild lag)."); DebugAILogging = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("Advanced", "DebugAILogging", false, "Whether to enable logging for AI (can cause extreme lag)."); } } public static class Utils { private static readonly EventEnum InvalidEvent = (EventEnum)(-1); public static EventEnum ForcedEvent = InvalidEvent; public static EventEnum LastEvent = (EventEnum)0; public static bool IsEventForced => ForcedEvent != InvalidEvent; public static void ReplaceScrap(this SelectableLevel Level, string ItemName, int Rarity, int MinValue, int MaxValue) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0090: Expected O, but got Unknown float oldMultiplier = RoundManager.Instance.scrapValueMultiplier; RoundManager.Instance.scrapValueMultiplier = 1f; List<SpawnableItemWithRarity> oldScrap = new List<SpawnableItemWithRarity>(Level.spawnableScrap); Item val = Object.Instantiate<Item>(FindItemByName(ItemName)); val.minValue = MinValue; val.maxValue = MaxValue; Level.spawnableScrap.Clear(); Level.spawnableScrap.Add(new SpawnableItemWithRarity { rarity = Rarity, spawnableItem = val }); BCManager.Instance.ExecuteAfterDelay(delegate { RoundManager.Instance.scrapValueMultiplier = oldMultiplier; Level.spawnableScrap = oldScrap; }, 12f); } private static Item FindItemByName(string ItemName) { return StartOfRound.Instance.allItemsList.itemsList.First((Item Item) => Item.itemName == ItemName); } public static bool IsObjectTypeOf<T>(this SpawnableMapObject MapObject, out T Component) { Component = MapObject.prefabToSpawn.GetComponentInChildren<T>(); return Component != null; } public static EventEnum SelectRandomEvent() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00a5: Unknown result type (might be due to invalid IL or missing references) if (ForcedEvent != InvalidEvent) { LastEvent = ForcedEvent; ForcedEvent = InvalidEvent; return LastEvent; } switch (EventRegistry.SelectableEvents.Count) { case 0: LastEvent = (EventEnum)0; return (EventEnum)0; case 1: return LastEvent = EventRegistry.SelectableEvents[0]; } EventEnum val; do { int num = Random.Range(0, EventRegistry.SelectableEvents.Count); val = EventRegistry.SelectableEvents[num]; Plugin.Logger.LogWarning((object)$"Selected event {num} ({val}), last event was {LastEvent}"); } while (val == LastEvent); return LastEvent = val; } public static bool TryFindEventByName(string Name, out EventEnum SelectedEvent) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown SelectedEvent = (EventEnum)(int)EventRegistry.AllEvents.TryGetFirst((KeyValuePair<string, EventEnum> EventName) => EventName.Key.StartsWith(Name, StringComparison.InvariantCultureIgnoreCase), out var Found).Value; return Found; } public static void SendEventMessage(IEvent Event) { string text = Event.Positivity switch { EventPositivity.Positive => "green", EventPositivity.Neutral => "white", EventPositivity.Negative => "red", EventPositivity.Golden => "orange", _ => "white", }; HUDManager.Instance.AddTextToChatOnServer("<color=yellow>EVENT<color=white>:</color></color>\n<color=" + text + ">" + Event.Name + "</color>\n<color=white><size=70%>" + Event.Description + "</size></color>", -1); } public static bool IsEmpty<T>(this IEnumerable<T> Collection) { return !Collection.Any(); } private static TSource TryGetFirst<TSource>(this IEnumerable<TSource> Source, Func<TSource, bool> Predicate, out bool Found) { foreach (TSource item in Source) { if (Predicate(item)) { Found = true; return item; } } Found = false; return default(TSource); } } public static class PluginInfo { public const string PLUGIN_GUID = "Sculas.BrutalCompanyAdditions"; public const string PLUGIN_NAME = "BrutalCompanyAdditions"; public const string PLUGIN_VERSION = "2.1.1"; } } namespace BrutalCompanyAdditions.Patches { public static class AIPatches { private static bool _patchFailed; [HarmonyPatch(typeof(MenuManager), "Start")] [HarmonyPrefix] public static void ShowPatchFailedMessage(MenuManager __instance) { if (!__instance.isInitScene && _patchFailed) { __instance.DisplayMenuNotification("[BrutalCompanyAdditions]\n\nA patch failed to apply. Report this issue together with your log file.", "[ Back ]"); _patchFailed = false; } } [HarmonyPatch(typeof(Turret), "Update")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> TurretPlayerDamagePatch(IEnumerable<CodeInstruction> instructions) { FieldInfo healthField = AccessTools.Field(typeof(PlayerControllerB), "health"); FieldInfo controllerField = AccessTools.Field(typeof(GameNetworkManager), "localPlayerController"); int modified = 0; CodeInstruction lastInstruction = null; foreach (CodeInstruction instruction in instructions) { if (lastInstruction != null && modified < 2 && instruction.opcode == OpCodes.Ldc_I4_S && lastInstruction.opcode == OpCodes.Ldfld && (CodeInstructionExtensions.OperandIs(lastInstruction, (MemberInfo)healthField) || CodeInstructionExtensions.OperandIs(lastInstruction, (MemberInfo)controllerField))) { Plugin.Logger.LogInfo((object)$"Patching turret damage; m = {modified}, c = {instruction}, l = {lastInstruction}"); modified++; lastInstruction = null; yield return instruction; yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(AIPatches), "GetTurretDamage", (Type[])null, (Type[])null)); } else { lastInstruction = instruction; yield return instruction; } } if (modified != 2) { Plugin.Logger.LogError((object)$"Failed to patch turret damage! Please report this issue. ({modified} != {2})"); _patchFailed = true; } else { Plugin.Logger.LogWarning((object)"Turret damage patched successfully!"); } } public static int GetTurretDamage(int original) { if (!EventRegistry.GetEventByType<MovingTurrets>().IsActive()) { return original; } return BCNetworkManager.Instance.TurretDamage.Value; } } public static class BCPatches { [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void InjectNetworkManager() { NetworkManager.Singleton.AddNetworkPrefab(Plugin.BCNetworkManagerPrefab); } [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPostfix] private static void SpawnNetworkManager() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { Object.Instantiate<GameObject>(Plugin.BCNetworkManagerPrefab, Vector3.zero, Quaternion.identity).GetComponent<NetworkObject>().Spawn(false); } } [HarmonyPatch(typeof(RoundManager), "DespawnPropsAtEndOfRound")] [HarmonyPostfix] private static void HandleCustomEventEnd(ref RoundManager __instance) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected I4, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)__instance).IsHost) { EventEnum lastEvent = Utils.LastEvent; BCNetworkManager.Instance.ClearCurrentEvent((int)lastEvent); if (EventRegistry.IsCustomEvent(lastEvent)) { IEvent @event = EventRegistry.GetEvent(lastEvent); Plugin.Logger.LogWarning((object)("Ending custom event " + @event.Name + "... (server)")); @event.OnEnd(); } } } [HarmonyPatch(typeof(Plugin), "SelectRandomEvent")] [HarmonyPrefix] public static bool InjectCustomEventsServer(ref EventEnum __result) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected I4, but got Unknown Plugin.Logger.LogWarning((object)"Injecting custom events... (server)"); EventEnum val = Utils.SelectRandomEvent(); if (EventRegistry.IsCustomEvent(val)) { IEvent @event = EventRegistry.GetEvent(val); Plugin.Logger.LogWarning((object)("Selected custom event " + @event.Name)); } else { Plugin.Logger.LogWarning((object)$"Selected original event {val}"); } __result = (EventEnum)(int)val; return false; } [HarmonyPatch(typeof(Plugin), "HandleEventSpecificAdjustments")] [HarmonyPrefix] public static bool InjectEventHandlers(ref EventEnum eventEnum, ref SelectableLevel newLevel) { if (newLevel.sceneName == "CompanyBuilding") { Plugin.Logger.LogWarning((object)"Landed at The Company Building, skipping..."); eventEnum = (EventEnum)0; return true; } if (!EventRegistry.IsCustomEvent(eventEnum)) { Plugin.Logger.LogWarning((object)$"Event {eventEnum} is not a custom event, skipping..."); return true; } IEvent @event = EventRegistry.GetEvent(eventEnum); Plugin.Logger.LogWarning((object)("Handling custom event " + @event.Name + "... (server)")); Utils.SendEventMessage(@event); @event.ExecuteServer(newLevel); BCNetworkManager.Instance.SetCurrentEvent((int)eventEnum, newLevel.levelID); return false; } } [HarmonyPatch(typeof(Terminal))] public class TerminalPatches { private const string ForceEventUsage = "Usage: forceevent [event name, partial allowed]"; private static readonly string AllEventNames = "Available events: " + GeneralExtensions.Join<string>((IEnumerable<string>)EventRegistry.AllEvents.Keys, (Func<string, string>)null, ", "); [HarmonyPostfix] [HarmonyPatch("ParsePlayerSentence")] public static void BCTerminalParser(ref Terminal __instance, ref TerminalNode __result) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) string text = __instance.screenText.text; int textAdded = __instance.textAdded; int length = text.Length; int num = length - textAdded; (string, string) tuple = ParseCommand(text.Substring(num, length - num)); string item = tuple.Item1; string item2 = tuple.Item2; string text2 = item; if (!(text2 == "forceevent")) { return; } if (((NetworkBehaviour)__instance).IsHost) { EventEnum SelectedEvent; if (string.IsNullOrWhiteSpace(item2)) { string text3 = (Utils.IsEventForced ? ("Currently forced event: " + EventRegistry.GetEventName(Utils.ForcedEvent)) : "No event is currently forced."); Respond(out __result, text3 + "\n\nUsage: forceevent [event name, partial allowed]\n\n" + AllEventNames); } else if (!Utils.TryFindEventByName(item2, out SelectedEvent)) { Respond(out __result, "Invalid event name: " + item2 + "\n\nUsage: forceevent [event name, partial allowed]\n\n" + AllEventNames); } else { Utils.ForcedEvent = SelectedEvent; Respond(out __result, "Forced next event to: " + EventRegistry.GetEventName(SelectedEvent)); } } else if (!((NetworkBehaviour)__instance).IsHost) { Respond(out __result, "You must be the host to use this command!"); } } private static (string, string) ParseCommand(string command) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) string[] array = command.ToLower().Split(' '); return (array[0], GeneralExtensions.Join<string>((IEnumerable<string>)array[Range.StartAt(Index.op_Implicit(1))], (Func<string, string>)null, " ")); } private static void Respond(out TerminalNode node, string text, bool clearPreviousText = true) { node = ScriptableObject.CreateInstance<TerminalNode>(); node.displayText = text + "\n\n\n"; node.clearPreviousText = clearPreviousText; } } } namespace BrutalCompanyAdditions.Objects { public class AICollisionDetect : MonoBehaviour { private const float DetectionRadius = 2.5f; private int _doorLayerMask; private Collider[] _doorColliders; public bool canOpenDoors = true; public float openDoorSpeedMultiplier = 1f; private void Start() { _doorLayerMask = LayerMask.GetMask(new string[1] { "InteractableObject" }); _doorColliders = (Collider[])(object)new Collider[8]; } private void FixedUpdate() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!canOpenDoors) { return; } int num = Physics.OverlapSphereNonAlloc(((Component)this).transform.position, 2.5f, _doorColliders, _doorLayerMask, (QueryTriggerInteraction)1); if (num == 0) { return; } DoorLock val = default(DoorLock); for (int i = 0; i < num; i++) { if (((Component)_doorColliders[i]).CompareTag("InteractTrigger") && ((Component)_doorColliders[i]).TryGetComponent<DoorLock>(ref val) && !val.isLocked && !val.isDoorOpened) { DoorLock obj = val; obj.enemyDoorMeter += Time.fixedDeltaTime * openDoorSpeedMultiplier; if (!(val.enemyDoorMeter <= 1f)) { val.enemyDoorMeter = 0f; ((Component)val).GetComponent<AnimatedObjectTrigger>().TriggerAnimationNonPlayer(false, true, false); val.OpenDoorAsEnemyServerRpc(); } } } } } public class BCManager : MonoBehaviour { public static BCManager Instance { get; private set; } private void Awake() { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); Plugin.Logger.LogWarning((object)"BCManager initialized!"); } public void ExecuteAfterDelay(Action Action, float Delay) { ((MonoBehaviour)this).StartCoroutine(DelayedExecution(Action, Delay)); } private static IEnumerator DelayedExecution(Action Action, float Delay) { yield return (object)new WaitForSeconds(Delay); Action(); } } public class BCNetworkManager : NetworkBehaviour { private const string Tag = "[BCNetworkManager]"; private readonly NetworkVariable<CurrentNetEvent> _currentEvent = new NetworkVariable<CurrentNetEvent>(default(CurrentNetEvent), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public readonly NetworkVariable<int> TurretDamage = new NetworkVariable<int>(PluginConfig.TurretDamage.Value, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public static BCNetworkManager Instance { get; private set; } private void Awake() { Instance = this; Log("BCNetworkManager initialized!"); NetworkVariable<CurrentNetEvent> currentEvent = _currentEvent; currentEvent.OnValueChanged = (OnValueChangedDelegate<CurrentNetEvent>)(object)Delegate.Combine((Delegate?)(object)currentEvent.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<CurrentNetEvent>(OnCurrentEventChanged)); } public void SetCurrentEvent(int EventId, int LevelId) { _currentEvent.Value = new CurrentNetEvent { EventId = EventId, LevelId = LevelId, IsEnding = false }; } public void ClearCurrentEvent(int EventId) { int levelID = RoundManager.Instance.currentLevel.levelID; _currentEvent.Value = new CurrentNetEvent { EventId = EventId, LevelId = levelID, IsEnding = true }; } private void OnCurrentEventChanged(CurrentNetEvent OldEvent, CurrentNetEvent NewEvent) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (((NetworkBehaviour)this).IsServer || OldEvent.Equals(NewEvent)) { return; } Log($"Received new event: {NewEvent}, old event was {OldEvent}"); Log("Injecting custom events... (client)"); EventEnum eventId = (EventEnum)NewEvent.EventId; if (EventRegistry.IsCustomEvent(eventId)) { IEvent @event = EventRegistry.GetEvent(eventId); if (NewEvent.IsEnding) { Log("Ending custom event " + @event.Name + "... (client)"); @event.OnEnd(); } else { Log("Handling custom event " + @event.Name + "... (client)"); @event.ExecuteClient(StartOfRound.Instance.levels[NewEvent.LevelId]); } } } private static void Log(string Message) { Plugin.Logger.LogWarning((object)("[BCNetworkManager] " + Message)); } protected override void __initializeVariables() { if (_currentEvent == null) { throw new Exception("BCNetworkManager._currentEvent cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)_currentEvent).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_currentEvent, "_currentEvent"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)_currentEvent); if (TurretDamage == null) { throw new Exception("BCNetworkManager.TurretDamage cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)TurretDamage).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)TurretDamage, "TurretDamage"); base.NetworkVariableFields.Add((NetworkVariableBase)(object)TurretDamage); ((NetworkBehaviour)this).__initializeVariables(); } protected internal override string __getTypeName() { return "BCNetworkManager"; } } public struct CurrentNetEvent : INetworkSerializable, IEquatable<CurrentNetEvent> { public int EventId; public int LevelId; public bool IsEnding; public void NetworkSerialize<T>(BufferSerializer<T> Serializer) where T : IReaderWriter { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (Serializer.IsReader) { FastBufferReader fastBufferReader = Serializer.GetFastBufferReader(); ((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<int>(ref EventId, default(ForPrimitives)); ((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<int>(ref LevelId, default(ForPrimitives)); ((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<bool>(ref IsEnding, default(ForPrimitives)); } else { FastBufferWriter fastBufferWriter = Serializer.GetFastBufferWriter(); ((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<int>(ref EventId, default(ForPrimitives)); ((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<int>(ref LevelId, default(ForPrimitives)); ((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<bool>(ref IsEnding, default(ForPrimitives)); } } public bool Equals(CurrentNetEvent Other) { if (EventId == Other.EventId && LevelId == Other.LevelId) { return IsEnding == Other.IsEnding; } return false; } public override string ToString() { return $"(eid: {EventId}, lid: {LevelId}, ending: {IsEnding})"; } } [RequireComponent(typeof(NavMeshAgent))] public class MovingTurretAI : NetworkBehaviour { private enum AIState { Roaming, Chasing } private const float AIIntervalTime = 0.2f; public const int DefaultPlayerDamage = 25; private const float PlayerLostIntervalTime = 0.075f; private const float PlayerLostMinTime = 1.5f; private const float PlayerLostMaxTime = -5f; private const float OpenDoorSpeedMultiplier = 0.5f; private const bool CanOpenDoorsWhileFiring = false; private const float AngularSpeed = 150f; private const float RoamingSpeed = 1.5f; private const float RoamingAcceleration = 4f; private const float ChasingSpeed = 2.5f; private const float ChasingAcceleration = 8f; private const float FiringSpeed = 0f; private const float FiringAcceleration = 0f; private const double RoamingCheckForPlayerIntervalTime = 0.05000000074505806; private const double ChasingCheckForPlayerIntervalTime = 0.07500000298023224; private const float RoamingRotationRange = 55f; private const float ChasingRotationRange = 65f; private const float UpdatePositionThreshold = 1f; private const float SyncMovementSpeed = 0.22f; private bool _showDebugText; private TextMesh _debugText; private GameObject _debugTextObject; private Vector3 _serverPosition; private Vector3 _tempVelocity; private float _previousYRotation; private float _targetYRotation; private NavMeshAgent _agent; private Turret _turret; private GameObject[] _aiNodes; private AICollisionDetect _collisionDetect; private double _updateAIInterval; private double _checkForPlayerInterval; private double _setDestinationToPlayerInterval; private AIState _aiState; private bool _hasTarget; private PlayerControllerB _targetedPlayer; private bool _lostPlayerInChase; private float _lastSeenTimer; private Vector3 _lastKnownPlayerPosition; private Collider[] _nearPlayerColliders; private Coroutine _searchCoroutine; private Coroutine _chooseTargetNodeCoroutine; private AISearchRoutine _currentSearch; private float _pathDistance; private NavMeshPath _path1; public override void OnDestroy() { ((NetworkBehaviour)this).OnDestroy(); Object.Destroy((Object)(object)_agent); if (_showDebugText) { Object.Destroy((Object)(object)_debugTextObject); } } private void Start() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown _serverPosition = ((Component)this).transform.position; _agent = ((Component)this).GetComponent<NavMeshAgent>(); _turret = ((Component)this).GetComponentInChildren<Turret>(); if (!((NetworkBehaviour)this).IsServer) { ((Behaviour)_agent).enabled = false; return; } _collisionDetect = ((Component)_turret).gameObject.AddComponent<AICollisionDetect>(); _collisionDetect.openDoorSpeedMultiplier = 0.5f; _agent.stoppingDistance = 0f; _agent.angularSpeed = 150f; _agent.radius = 1.21f; _agent.height = 3.3f; _agent.obstacleAvoidanceType = (ObstacleAvoidanceType)1; _agent.avoidancePriority = 50; _agent.areaMask = 31; _aiNodes = GameObject.FindGameObjectsWithTag("AINode"); _currentSearch = new AISearchRoutine(); _path1 = new NavMeshPath(); _nearPlayerColliders = (Collider[])(object)new Collider[StartOfRound.Instance.allPlayerScripts.Length + 1]; _showDebugText = PluginConfig.DebugAI.Value && ((NetworkBehaviour)this).IsServer; if (_showDebugText) { GameObject val = new GameObject("BCA AI Debug Text"); val.transform.parent = _turret.aimPoint; val.transform.localPosition = new Vector3(0f, 0.5f, 0f); val.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f); val.transform.rotation = Quaternion.Euler(0f, 90f, 0f); _debugTextObject = val; _debugText = _debugTextObject.AddComponent<TextMesh>(); _debugText.fontSize = 100; _debugText.anchor = (TextAnchor)4; } StartRoaming(); } private void Update() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_007f: Unknown result type (might be due to invalid IL or missing references) //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_014f: 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_0165: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Invalid comparison between Unknown and I4 //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) if (StartOfRound.Instance.livingPlayers == 0) { return; } if (!((NetworkBehaviour)this).IsServer) { Transform transform = ((Component)this).transform; ((Component)this).transform.position = Vector3.SmoothDamp(transform.position, _serverPosition, ref _tempVelocity, 0.22f); Vector3 eulerAngles = transform.eulerAngles; ((Vector3)(ref eulerAngles))..ctor(eulerAngles.x, Mathf.LerpAngle(eulerAngles.y, _targetYRotation, 15f * Time.deltaTime), eulerAngles.z); ((Component)this).transform.eulerAngles = eulerAngles; return; } if (_showDebugText) { _debugText.text = $"{_aiState} (lostPlayer = {_lostPlayerInChase}, hasTarget = {_hasTarget})"; } if (_hasTarget && (Object)(object)_targetedPlayer != (Object)null) { if (_setDestinationToPlayerInterval <= 0.0) { _setDestinationToPlayerInterval = 0.25; _agent.SetDestination(RoundManager.Instance.GetNavMeshPosition(((Component)_targetedPlayer).transform.position, RoundManager.Instance.navHit, 2.7f, -1)); } else { Vector3 position = ((Component)_targetedPlayer).transform.position; _agent.SetDestination(new Vector3(position.x, _agent.destination.y, position.z)); _setDestinationToPlayerInterval -= Time.deltaTime; } } if (!_turret.turretActive) { ((Behaviour)_agent).enabled = false; return; } ((Behaviour)_agent).enabled = true; if (_updateAIInterval >= 0.0) { _updateAIInterval -= Time.deltaTime; } else { SyncPositionToClients(); DoAIInterval(); _updateAIInterval = 0.20000000298023224; } if ((double)Mathf.Abs(_previousYRotation - ((Component)this).transform.eulerAngles.y) > 6.0) { _previousYRotation = ((Component)this).transform.eulerAngles.y; _targetYRotation = _previousYRotation; UpdateEnemyRotationClientRpc((short)_previousYRotation); } PlayerControllerB Player; switch (_aiState) { case AIState.Roaming: if (_checkForPlayerInterval <= 0.05000000074505806) { _checkForPlayerInterval += Time.deltaTime; break; } _checkForPlayerInterval = 0.0; if (CheckLineOfSightForPlayer(out Player, 55f, 3f, AngleRangeCheck: true)) { StartChasing(Player); } break; case AIState.Chasing: { TurretMode turretMode = _turret.turretMode; if (turretMode - 2 <= 1) { SetAgentSpeed(0f, 0f); _collisionDetect.canOpenDoors = false; } else { SetAgentSpeed(2.5f, 8f); _collisionDetect.canOpenDoors = true; } if (_checkForPlayerInterval <= 0.07500000298023224) { _checkForPlayerInterval += Time.deltaTime; break; } _checkForPlayerInterval = 0.0; if (_lostPlayerInChase) { if (CheckLineOfSightForPlayer(out Player, 65f, 3f)) { _lastSeenTimer = 0f; _lostPlayerInChase = false; SetTargetedPlayer(Player); break; } _lastSeenTimer -= 0.075f; if (!(_lastSeenTimer >= -5f)) { StartRoaming(); } } else if (CheckLineOfSightForPlayer(out Player, 65f, 3f)) { _lastSeenTimer = 0f; _lastKnownPlayerPosition = ((Component)Player).transform.position; SetTargetedPlayer(Player); } else { _lastSeenTimer += 0.075f; if (!(_lastSeenTimer <= 1.5f)) { _lostPlayerInChase = true; } } break; } default: throw new ArgumentOutOfRangeException(); } } private void StartRoaming() { if (SetAIState(AIState.Roaming)) { SetTargetedPlayer(null); _checkForPlayerInterval = 0.0; _lostPlayerInChase = false; _currentSearch.searchWidth = 25f; SetAgentSpeed(); } } private void StartChasing(PlayerControllerB Player) { if (SetAIState(AIState.Chasing)) { SetTargetedPlayer(Player); _checkForPlayerInterval = 0.0; _lostPlayerInChase = false; SetAgentSpeed(2.5f, 8f); } } private void DoAIInterval() { LogAI(() => "Starting AI interval"); switch (_aiState) { case AIState.Roaming: AIRoaming(); break; case AIState.Chasing: AIChasing(); break; default: throw new ArgumentOutOfRangeException(); } } private void AIRoaming() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!_currentSearch.inProgress) { LogAI(() => "Starting player search"); StartSearch(((Component)this).transform.position); } } private void AIChasing() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) CheckForVeryClosePlayer(); if (_lostPlayerInChase) { if (!_currentSearch.inProgress) { _currentSearch.searchWidth = 30f; StartSearch(_lastKnownPlayerPosition); LogAI(() => "Lost player in chase, starting search at last known position"); } } else if (_currentSearch.inProgress) { StopSearch(_currentSearch); LogAI(() => "Found player during chase, targeting player"); } } private void OnSearchFinished() { _currentSearch.searchWidth = Mathf.Clamp(_currentSearch.searchWidth + 10f, 1f, 100f); } public void StartSearch(Vector3 StartOfSearch) { //IL_0026: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown StopSearch(_currentSearch); if (_currentSearch == null) { _currentSearch = new AISearchRoutine(); } _currentSearch.currentSearchStartPosition = StartOfSearch; if (_currentSearch.unsearchedNodes.IsEmpty()) { _currentSearch.unsearchedNodes = _aiNodes.ToList(); } _searchCoroutine = ((MonoBehaviour)this).StartCoroutine(PlayerSearchRoutine()); _currentSearch.inProgress = true; } public void StopSearch(AISearchRoutine Search, bool Clear = true) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) if (Search != null) { if (_searchCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_searchCoroutine); } if (_chooseTargetNodeCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_chooseTargetNodeCoroutine); } Search.calculatingNodeInSearch = false; Search.inProgress = false; if (Clear) { Search.unsearchedNodes = _aiNodes.ToList(); Search.timesFinishingSearch = 0; Search.nodesEliminatedInCurrentSearch = 0; Search.currentTargetNode = null; Search.currentSearchStartPosition = Vector3.zero; Search.nextTargetNode = null; Search.choseTargetNode = false; } } } private IEnumerator PlayerSearchRoutine() { yield return null; while (_searchCoroutine != null) { yield return null; if (_currentSearch.unsearchedNodes.IsEmpty()) { OnSearchFinished(); if (!_currentSearch.loopSearch) { _currentSearch.inProgress = false; _currentSearch = null; break; } _currentSearch.unsearchedNodes = _aiNodes.ToList(); AISearchRoutine currentSearch = _currentSearch; currentSearch.timesFinishingSearch++; _currentSearch.nodesEliminatedInCurrentSearch = 0; yield return (object)new WaitForSeconds(1f); } if (_currentSearch.choseTargetNode && _currentSearch.unsearchedNodes.Contains(_currentSearch.nextTargetNode)) { _currentSearch.currentTargetNode = _currentSearch.nextTargetNode; } else { _currentSearch.waitingForTargetNode = true; StartCalculatingNextTargetNode(); yield return (object)new WaitUntil((Func<bool>)(() => _currentSearch.choseTargetNode)); } _currentSearch.waitingForTargetNode = false; if (_currentSearch.unsearchedNodes.IsEmpty() || (Object)(object)_currentSearch.currentTargetNode == (Object)null) { continue; } _currentSearch.unsearchedNodes.Remove(_currentSearch.currentTargetNode); _agent.SetDestination(RoundManager.Instance.GetNavMeshPosition(_currentSearch.currentTargetNode.transform.position, RoundManager.Instance.navHit, -1f, -1)); int i = _currentSearch.unsearchedNodes.Count - 1; while (i >= 0) { if ((double)Vector3.Distance(_currentSearch.currentTargetNode.transform.position, _currentSearch.unsearchedNodes[i].transform.position) < (double)_currentSearch.searchPrecision) { EliminateNodeFromSearch(i); } if (i % 10 == 0) { yield return null; } int num = i - 1; i = num; } StartCalculatingNextTargetNode(); int timeSpent = 0; while (_searchCoroutine != null) { int num = timeSpent + 1; timeSpent = num; if (num >= 32) { break; } yield return (object)new WaitForSeconds(0.5f); if ((double)Vector3.Distance(((Component)this).transform.position, _currentSearch.currentTargetNode.transform.position) < (double)_currentSearch.searchPrecision) { break; } } } } private void StartCalculatingNextTargetNode() { if (_chooseTargetNodeCoroutine == null) { _currentSearch.choseTargetNode = false; _chooseTargetNodeCoroutine = ((MonoBehaviour)this).StartCoroutine(ChooseNextNodeInSearchRoutine()); } else if (!_currentSearch.calculatingNodeInSearch) { _currentSearch.choseTargetNode = false; _currentSearch.calculatingNodeInSearch = true; ((MonoBehaviour)this).StopCoroutine(_chooseTargetNodeCoroutine); _chooseTargetNodeCoroutine = ((MonoBehaviour)this).StartCoroutine(ChooseNextNodeInSearchRoutine()); } } private IEnumerator ChooseNextNodeInSearchRoutine() { yield return null; float closestDist = 500f; GameObject chosenNode = null; int i = _currentSearch.unsearchedNodes.Count - 1; while (i >= 0) { if (i % 5 == 0) { yield return null; } if (Vector3.Distance(_currentSearch.currentSearchStartPosition, _currentSearch.unsearchedNodes[i].transform.position) > _currentSearch.searchWidth) { EliminateNodeFromSearch(i); } else if (PathIsIntersectedByLineOfSight(_currentSearch.unsearchedNodes[i].transform.position, CalculatePathDistance: true, AvoidLineOfSight: false)) { EliminateNodeFromSearch(i); } else if (_pathDistance < closestDist) { closestDist = _pathDistance; chosenNode = _currentSearch.unsearchedNodes[i]; } int num = i - 1; i = num; } if (_currentSearch.waitingForTargetNode) { _currentSearch.currentTargetNode = chosenNode; } else { _currentSearch.nextTargetNode = chosenNode; } _currentSearch.choseTargetNode = true; _currentSearch.calculatingNodeInSearch = false; _chooseTargetNodeCoroutine = null; } private bool PathIsIntersectedByLineOfSight(Vector3 TargetPos, bool CalculatePathDistance = false, bool AvoidLineOfSight = true) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) _pathDistance = 0f; if (!_agent.CalculatePath(TargetPos, _path1)) { return true; } if ((double)Vector3.Distance(_path1.corners[^1], RoundManager.Instance.GetNavMeshPosition(TargetPos, RoundManager.Instance.navHit, 2.7f, -1)) > 1.5) { return true; } if (CalculatePathDistance) { for (int i = 1; i < _path1.corners.Length; i++) { _pathDistance += Vector3.Distance(_path1.corners[i - 1], _path1.corners[i]); if (AvoidLineOfSight && Physics.Linecast(_path1.corners[i - 1], _path1.corners[i], 262144)) { return true; } } } else if (AvoidLineOfSight) { for (int j = 1; j < _path1.corners.Length; j++) { if (Physics.Linecast(_path1.corners[j - 1], _path1.corners[j], 262144)) { return true; } } } return false; } public void SyncPositionToClients() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (!(Vector3.Distance(_serverPosition, ((Component)this).transform.position) <= 1f)) { _serverPosition = ((Component)this).transform.position; UpdateEnemyPositionClientRpc(_serverPosition); } } [ClientRpc] private void UpdateEnemyPositionClientRpc(Vector3 NewPosition) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2743561777u, val, (RpcDelivery)0); ((FastBufferWriter)(ref val2)).WriteValueSafe(ref NewPosition); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2743561777u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost)) { _serverPosition = NewPosition; } } } [ClientRpc] private void UpdateEnemyRotationClientRpc(short RotationY) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1780689525u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, RotationY); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1780689525u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost)) { _previousYRotation = ((Component)this).transform.eulerAngles.y; _targetYRotation = RotationY; } } } private void SetAgentSpeed(float Speed = 1.5f, float Acceleration = 4f) { _agent.speed = Speed; _agent.acceleration = Acceleration; } private bool CheckLineOfSightForPlayer(out PlayerControllerB Player, float Width, float Radius = 2f, bool AngleRangeCheck = false) { _turret.rotationRange = Width; Player = _turret.CheckForPlayersInLineOfSight(Radius, AngleRangeCheck); return (Object)(object)Player != (Object)null; } private void CheckForVeryClosePlayer() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = default(PlayerControllerB); if (Physics.OverlapSphereNonAlloc(((Component)this).transform.position, 1.5f, _nearPlayerColliders, 8, (QueryTriggerInteraction)1) > 0 && ((Component)((Component)_nearPlayerColliders[0]).transform).TryGetComponent<PlayerControllerB>(ref val) && !((Object)(object)val == (Object)(object)_targetedPlayer) && !Physics.Linecast(((Component)this).transform.position + Vector3.up * 0.3f, ((Component)val).transform.position, StartOfRound.Instance.collidersAndRoomMask)) { SetTargetedPlayer(val); } } private void EliminateNodeFromSearch(int Index) { _currentSearch.unsearchedNodes.RemoveAt(Index); AISearchRoutine currentSearch = _currentSearch; currentSearch.nodesEliminatedInCurrentSearch++; } private bool SetAIState(AIState State) { if (_aiState == State) { return false; } _aiState = State; LogAI(() => $"Setting AI state to {State}"); return true; } private void SetTargetedPlayer([CanBeNull] PlayerControllerB Player) { _targetedPlayer = Player; _hasTarget = (Object)(object)Player != (Object)null; LogAI(() => $"Setting targeted player to {Player}"); } private void LogAI(Func<string> Message) { if (PluginConfig.DebugAILogging.Value) { Plugin.Logger.LogInfo((object)string.Format("[{0}] (state = {1}) {2}", "MovingTurretAI", _aiState, Message())); } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } [RuntimeInitializeOnLoadMethod] internal static void InitializeRPCS_MovingTurretAI() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown NetworkManager.__rpc_func_table.Add(2743561777u, new RpcReceiveHandler(__rpc_handler_2743561777)); NetworkManager.__rpc_func_table.Add(1780689525u, new RpcReceiveHandler(__rpc_handler_1780689525)); } private static void __rpc_handler_2743561777(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { Vector3 newPosition = default(Vector3); ((FastBufferReader)(ref reader)).ReadValueSafe(ref newPosition); target.__rpc_exec_stage = (__RpcExecStage)2; ((MovingTurretAI)(object)target).UpdateEnemyPositionClientRpc(newPosition); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1780689525(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { short rotationY = default(short); ByteUnpacker.ReadValueBitPacked(reader, ref rotationY); target.__rpc_exec_stage = (__RpcExecStage)2; ((MovingTurretAI)(object)target).UpdateEnemyRotationClientRpc(rotationY); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "MovingTurretAI"; } } } namespace BrutalCompanyAdditions.Events { public class BlingBling : IEvent { public string Name => "Bling bling"; public string Description => "So many gold bars! ...right?"; public EventPositivity Positivity => EventPositivity.Neutral; public void ExecuteServer(SelectableLevel Level) { Level.ReplaceScrap("Gold bar", 100, 1, 10); } public void ExecuteClient(SelectableLevel Level) { } public void OnEnd() { } } public interface IEvent { string Name { get; } string Description { get; } EventPositivity Positivity { get; } void ExecuteServer(SelectableLevel Level); void ExecuteClient(SelectableLevel Level); void OnEnd(); } public enum EventPositivity { Positive, Neutral, Negative, Golden } public class MovingTurrets : IEvent { private GameObject _turretPrefab; public string Name => "Since when can they move?!"; public string Description => "Did someone give them wheels?"; public EventPositivity Positivity => EventPositivity.Negative; public void ExecuteServer(SelectableLevel Level) { BCNetworkManager.Instance.TurretDamage.Value = PluginConfig.TurretDamage.Value; Execute(Level); } public void ExecuteClient(SelectableLevel Level) { Execute(Level); } private void Execute(SelectableLevel Level) { SpawnableMapObject[] spawnableMapObjects = Level.spawnableMapObjects; foreach (SpawnableMapObject val in spawnableMapObjects) { if (val.IsObjectTypeOf<Turret>(out var _)) { (_turretPrefab = val.prefabToSpawn).AddComponent<MovingTurretAI>(); break; } } } public void OnEnd() { if (!((Object)(object)_turretPrefab == (Object)null)) { MovingTurretAI component = _turretPrefab.GetComponent<MovingTurretAI>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } } } public class TheVault : IEvent { public string Name => "Got any stock?"; public string Description => "They used to say Fort Knox was buried here..."; public EventPositivity Positivity => EventPositivity.Golden; public void ExecuteServer(SelectableLevel Level) { Level.ReplaceScrap("Gold bar", 100, 100, 350); } public void ExecuteClient(SelectableLevel Level) { } public void OnEnd() { } } }