using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.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()
{
}
}
}