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 NotControlCompany v1.0.0
ControlCompany.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ControlCompany.Core; using ControlCompany.Core.Config; using ControlCompany.Core.Enemy; using ControlCompany.Core.Extentions; using ControlCompany.Core.Input; using ControlCompany.Core.UI; using ControlCompany.Patches; using Dissonance; using GameNetcodeStuff; using HarmonyLib; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ControlCompany")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ControlCompany")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("dfed064e-ab44-4aa7-b361-7a59370d39a8")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace ControlCompany { [BepInPlugin("ControlCompany.ControlCompany", "ControlCompany", "1.0.6")] public class ControlCompanyPlugin : BaseUnityPlugin { private const string modGUID = "ControlCompany.ControlCompany"; private const string modName = "ControlCompany"; private const string modVersion = "1.0.6"; private readonly Harmony harmony = new Harmony("ControlCompany.ControlCompany"); public static ControlCompanyPlugin Instance; internal ManualLogSource logger; private bool isInitialized; private bool ranInitializationScripts; private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown if ((Object)(object)Instance == (Object)null) { Instance = this; } logger = Logger.CreateLogSource("ControlCompany.ControlCompany"); logger.LogInfo((object)"Loaded ControlCompany. Patching."); ApplyPatches(); logger.LogInfo((object)"Completed patching. Initializing control center."); GameObject val = new GameObject("control_company_control_center"); val.AddComponent<ControlCenter>(); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<UIManager>(); val.AddComponent<ConfigManager>().Initialize(((BaseUnityPlugin)this).Config); Object.DontDestroyOnLoad((Object)val); logger.LogInfo((object)"Completed initialization."); isInitialized = true; } private void ApplyPatches() { harmony.PatchAll(typeof(ControlCompanyPlugin)); harmony.PatchAll(typeof(HUDManagerPatch)); harmony.PatchAll(typeof(StartOfRoundPatch)); harmony.PatchAll(typeof(PlayerControllerBPatch)); harmony.PatchAll(typeof(EnemyAIPatch)); harmony.PatchAll(typeof(TimeOfDayPatch)); } } } namespace ControlCompany.Patches { [HarmonyPatch(typeof(EnemyAI))] internal class EnemyAIPatch { [HarmonyPatch("ChangeOwnershipOfEnemy")] [HarmonyPrefix] private static bool ChangeOwnershipOfEnemyPrefix(EnemyAI __instance, ref ulong newOwnerClientId) { if ((Object)(object)ControlCenter.Instance != (Object)null) { if (ControlCenter.Instance.CurrentMode == ControlCenter.Mode.ENEMY) { if (ControlCenter.Instance.GetHostPlayer().actualClientId != newOwnerClientId && !ControlCenter.Instance.CurrentControlledEnemy.IsAIControlled) { return (Object)(object)ControlCenter.Instance.CurrentControlledEnemy.EnemyAI != (Object)(object)__instance; } return true; } return true; } return true; } [HarmonyPatch("ChangeEnemyOwnerServerRpc")] [HarmonyPrefix] private static bool ChangeEnemyOwnerServerRpcPrefix(EnemyAI __instance, ref ulong clientId) { if ((Object)(object)ControlCenter.Instance != (Object)null) { if (ControlCenter.Instance.CurrentMode == ControlCenter.Mode.ENEMY) { if (ControlCenter.Instance.GetHostPlayer().actualClientId != clientId && !ControlCenter.Instance.CurrentControlledEnemy.IsAIControlled) { return (Object)(object)ControlCenter.Instance.CurrentControlledEnemy.EnemyAI != (Object)(object)__instance; } return true; } return true; } return true; } } [HarmonyPatch(typeof(HUDManager))] internal class HUDManagerPatch { [HarmonyPatch("CanPlayerScan")] [HarmonyPostfix] private static void CanPlayerScanPostfix(ref bool __result) { if (__result && (Object)(object)ControlCenter.Instance != (Object)null) { __result = ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST; } } [HarmonyPatch("UpdateHealthUI")] [HarmonyPrefix] private static bool UpdateHealthUIPrefix() { if ((Object)(object)ControlCenter.Instance != (Object)null) { return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST; } return true; } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatch { [HarmonyPatch("PlayerLookInput")] [HarmonyPrefix] private static bool PlayerLookInputPrefix() { if ((Object)(object)ControlCenter.Instance != (Object)null) { return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST; } return true; } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatch { [HarmonyPatch("ShipHasLeft")] [HarmonyPrefix] private static void ShipHasLeftPrefix() { if ((Object)(object)ControlCenter.Instance != (Object)null) { ControlCenter.Instance.EndOfRoundCleanUp(); } } [HarmonyPatch("StartGame")] [HarmonyPostfix] private static void StartGamePostfix() { if ((Object)(object)ControlCenter.Instance != (Object)null) { ControlCenter.Instance.StartOfRoundInitialization(); } } } [HarmonyPatch(typeof(TimeOfDay))] internal class TimeOfDayPatch { [HarmonyPatch("VoteShipToLeaveEarly")] [HarmonyPrefix] private static bool VoteToLeaveEarly() { if ((Object)(object)ControlCenter.Instance != (Object)null) { return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST; } return true; } } } namespace ControlCompany.Core { internal static class Constants { public static Dictionary<int, string> ALL_LAYERS_DICT = (from index in Enumerable.Range(0, 32) where !string.IsNullOrEmpty(LayerMask.LayerToName(index)) select index).ToDictionary((int index) => index, (int index) => LayerMask.LayerToName(index)); public static LayerMask PLAYER_LOS_LAYER = LayerMask.op_Implicit(262144); public static LayerMask PLAYER_LAYER = LayerMask.op_Implicit(8); public static LayerMask ITERACTABLE_OBJ_LAYER = LayerMask.op_Implicit(512); public static LayerMask PROPS_LAYER = LayerMask.op_Implicit(64); public static LayerMask ENEMIES_LAYER = LayerMask.op_Implicit(524288); public static LayerMask PLAYER_RAGDOLL_LAYER = LayerMask.op_Implicit(1048576); } internal class ControlCenter : MonoBehaviour { public enum Mode { HOST, GHOST, ENEMY } public static ControlCenter Instance; private GameObject ghost; private EnemyController currentControlledEnemy; private int currentTargetIndex; private PlayerControllerB currentTarget; private Mode currentMode; private bool allowAllEnemies; private bool initialMicPushToTalkSetting; private bool hostDeadOnThisFrame; private bool isExtendedModeEnabled; private bool scrapSpawnMode; private int scrapSpawnPage; private int scrapSpawnPageSize = 10; private bool loadedConfig; private bool showUI = true; private float gameStartedTime; public Mode CurrentMode => currentMode; public EnemyController CurrentControlledEnemy => currentControlledEnemy; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } } private void Update() { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown if (!IsGameStarted()) { return; } if (!loadedConfig) { loadedConfig = true; ConfigManager.Instance.LoadPlayerKeybinds(); } if (((ButtonControl)InputKeys.TOGGLE_UI_KEY).wasPressedThisFrame) { showUI = !showUI; } gameStartedTime += Time.deltaTime; if (IsHost()) { if (((Object)(object)currentTarget == (Object)null || !currentTarget.isPlayerControlled || currentTarget.isPlayerDead) && GetAlivePlayers().Count > 0) { SetNextTargetPlayer(1); } if ((Object)(object)ghost == (Object)null) { GameObject val = new GameObject("ghost"); val.AddComponent<CustomPlayerController>().Initialize(GetHostPlayer().playerActions, CustomPlayerController.CameraMode.FIRST_PERSON); ghost = val; ghost.SetActive(false); } if (!hostDeadOnThisFrame && IsHostDead()) { hostDeadOnThisFrame = true; } if (currentMode != 0) { GetHostPlayer().isTypingChat = true; } InputUpdate(); } } private void InputUpdate() { //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) if (!IsGameStarted() || !IsHost()) { return; } if (((ButtonControl)InputKeys.EXTENDED_MODE_KEY).wasPressedThisFrame) { isExtendedModeEnabled = !isExtendedModeEnabled; allowAllEnemies = isExtendedModeEnabled; } switch (currentMode) { case Mode.ENEMY: if (!currentControlledEnemy.IsAIControlled && !currentControlledEnemy.EnemyAI.isEnemyDead) { if (InputKeys.ENEMY_PRIMARY_SKILL_BUTTON.wasPressedThisFrame) { currentControlledEnemy.UsePrimarySkill(); } else if (InputKeys.ENEMY_PRIMARY_SKILL_BUTTON.wasReleasedThisFrame) { currentControlledEnemy.ReleasePrimarySkill(); } else if (InputKeys.ENEMY_SECONDARY_SKILL_BUTTON.wasPressedThisFrame) { currentControlledEnemy.UseSecondarySkill(); } else if (InputKeys.ENEMY_SECONDARY_SKILL_BUTTON.wasReleasedThisFrame) { currentControlledEnemy.ReleaseSecondarySkill(); } currentControlledEnemy.SetLockEnemyRotation(((ButtonControl)InputKeys.LOCK_ENEMY_ROTATION_KEY).isPressed); } if (((ButtonControl)InputKeys.EXIT_KEY).wasPressedThisFrame) { EnableGhost(enable: true, ((Component)currentControlledEnemy).transform.position); bool enable = IsTargetInside(); ghost.GetComponentInChildren<CustomPlayerController>().EnableLight(enable); currentControlledEnemy.DestroyAndCleanUp(); currentMode = Mode.GHOST; } else if (((ButtonControl)InputKeys.ENEMY_TOGGLE_AI_KEY).wasPressedThisFrame) { currentControlledEnemy.ToggleAIControl(); } break; case Mode.HOST: if (((ButtonControl)InputKeys.HOST_GHOST_MODE_KEY).wasPressedThisFrame) { EnableGhost(enable: true, ((Component)currentTarget).gameObject.transform.position); bool enable2 = IsTargetInside(); ghost.GetComponentInChildren<CustomPlayerController>().EnableLight(enable2); EnableHostPlayer(enable: false); currentMode = Mode.GHOST; } else if (((ButtonControl)InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_LEFT).wasPressedThisFrame) { SetNextTargetPlayer(-1); } else if (((ButtonControl)InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_RIGHT).wasPressedThisFrame) { SetNextTargetPlayer(1); } if (isExtendedModeEnabled) { if (((ButtonControl)InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY).wasPressedThisFrame) { ((Component)GetHostPlayer()).gameObject.transform.position = RoundManager.FindMainEntrancePosition(true, false); GetHostPlayer().isInsideFactory = true; } else if (((ButtonControl)InputKeys.HOST_GIVE_CREDITS_KEY).wasPressedThisFrame) { Object.FindObjectOfType<Terminal>().groupCredits = 5000; } } break; case Mode.GHOST: if (!scrapSpawnMode) { bool isIndoor = IsTargetInside(); List<SpawnableEnemyWithRarity> spawnableEnemies = GetSpawnableEnemies(isIndoor); for (int i = 0; i < InputKeys.GHOST_SPAWN_ENEMY_KEYS.Count && i < spawnableEnemies.Count; i++) { if (((ButtonControl)InputKeys.GHOST_SPAWN_ENEMY_KEYS[i]).wasPressedThisFrame) { currentControlledEnemy = SpawnControllableEnemy(spawnableEnemies[i], ghost.transform.position, ghost.transform.rotation); EnableGhost(enable: false); currentMode = Mode.ENEMY; break; } } } else { List<SpawnableItemWithRarity> list = ExtensionMethods.Chunk(GetSpawnableScraps(), scrapSpawnPageSize).ToList()[scrapSpawnPage].ToList(); for (int j = 0; j < InputKeys.GHOST_SPAWN_ENEMY_KEYS.Count && j < list.Count; j++) { if (((ButtonControl)InputKeys.GHOST_SPAWN_ENEMY_KEYS[j]).wasPressedThisFrame) { SpawnScrap(list[j], ghost.transform.position); break; } } } if (((ButtonControl)InputKeys.EXIT_KEY).wasPressedThisFrame) { EnableGhost(enable: false); EnableHostPlayer(enable: true); currentMode = Mode.HOST; GetHostPlayer().isTypingChat = false; } _ = ((ButtonControl)Keyboard.current.upArrowKey).wasPressedThisFrame; if (scrapSpawnMode && ((ButtonControl)Keyboard.current.downArrowKey).wasPressedThisFrame) { int num = GetSpawnableScraps().Count / scrapSpawnPageSize; ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Total scraps: {GetSpawnableScraps().Count()}, final page of scrap: {num}"); scrapSpawnPage++; if (scrapSpawnPage > num) { scrapSpawnPage = 0; } } break; } } private bool IsTargetInside() { if ((Object)(object)currentTarget != (Object)null) { return currentTarget.isInsideFactory; } return false; } private void OnGUI() { if (!IsGameStarted() || !showUI) { return; } if (!IsHost()) { if (gameStartedTime < 30f) { UIManager.Instance.RenderNotHostLabel(((InputControl)InputKeys.TOGGLE_UI_KEY).displayName); } return; } switch (currentMode) { case Mode.ENEMY: UIManager.Instance.RenderEnemyControls(((InputControl)InputKeys.ENEMY_PRIMARY_SKILL_BUTTON).shortDisplayName, ((InputControl)InputKeys.ENEMY_SECONDARY_SKILL_BUTTON).shortDisplayName, ((InputControl)InputKeys.ENEMY_TOGGLE_AI_KEY).displayName, ((InputControl)InputKeys.EXIT_KEY).displayName, currentControlledEnemy, GetHostPlayer()); break; case Mode.HOST: UIManager.Instance.RenderHostControls(((InputControl)InputKeys.HOST_GHOST_MODE_KEY).displayName, ((InputControl)InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_LEFT).displayName, ((InputControl)InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_RIGHT).displayName, currentTarget, isExtendedModeEnabled, ((InputControl)InputKeys.HOST_GIVE_CREDITS_KEY).displayName, ((InputControl)InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY).displayName, ((InputControl)InputKeys.TOGGLE_UI_KEY).displayName); break; case Mode.GHOST: { bool isIndoor = IsTargetInside(); UIManager.Instance.RenderGhostControls(InputKeys.GHOST_SPAWN_ENEMY_KEYS.Select((KeyControl key) => ((InputControl)key).displayName).ToList(), ((InputControl)InputKeys.EXIT_KEY).displayName, GetSpawnableEnemies(isIndoor), ExtensionMethods.Chunk(GetSpawnableScraps(), scrapSpawnPageSize).ToList()[scrapSpawnPage].ToList(), GetHostPlayer(), scrapSpawnMode); break; } } } private bool IsHostDead() { return GetHostPlayer().isPlayerDead; } private void EnableGhost(bool enable) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) EnableGhost(enable, Vector3.zero); } private void EnableGhost(bool enable, Vector3 position) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (enable) { ghost.transform.position = position + new Vector3(0f, 0.5f, 0f); ghost.transform.rotation = Quaternion.identity; ghost.SetActive(true); } else { ghost.SetActive(false); } } private void EnableHostPlayer(bool enable) { //IL_008f: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB hostPlayer = GetHostPlayer(); MovementActions movement; if (!enable) { ResetMicPushToTalk(); HUDManager.Instance.HideHUD(false); ((Behaviour)StartOfRound.Instance.audioListener).enabled = true; movement = hostPlayer.playerActions.Movement; ((MovementActions)(ref movement)).PingScan.Disable(); } else { initialMicPushToTalkSetting = IngamePlayerSettings.Instance.settings.pushToTalk; ForceMicPushToTalk(); HUDManager.Instance.HideHUD(true); ((Behaviour)StartOfRound.Instance.audioListener).enabled = false; movement = hostPlayer.playerActions.Movement; ((MovementActions)(ref movement)).PingScan.Enable(); } } private void EnablePlayer2DMics(bool enable, List<PlayerControllerB> players) { foreach (PlayerControllerB player in players) { if (player.isHostPlayerObject) { continue; } AudioSource currentVoiceChatAudioSource = player.currentVoiceChatAudioSource; if (enable) { if ((Object)(object)currentVoiceChatAudioSource != (Object)null) { currentVoiceChatAudioSource.spatialBlend = 0f; } player.currentVoiceChatIngameSettings.set2D = true; player.voicePlayerState.Volume = 1f; } else { if ((Object)(object)currentVoiceChatAudioSource != (Object)null) { currentVoiceChatAudioSource.spatialBlend = 1f; } player.currentVoiceChatIngameSettings.set2D = false; player.voicePlayerState.Volume = 0f; } } } private void SetNextTargetPlayer(int direction) { List<PlayerControllerB> alivePlayers = GetAlivePlayers(); if (alivePlayers.Count == 0) { SetCurrentTargetToHost(); ControlCompanyPlugin.Instance.logger.LogMessage((object)"Alive player count is zero"); } else { currentTargetIndex += direction; if (currentTargetIndex >= alivePlayers.Count) { currentTargetIndex = 0; } else if (currentTargetIndex < 0) { currentTargetIndex = alivePlayers.Count - 1; } currentTargetIndex = Math.Min(Math.Max(0, currentTargetIndex), alivePlayers.Count - 1); currentTarget = alivePlayers[currentTargetIndex]; } ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Current target index: {currentTargetIndex}"); ControlCompanyPlugin.Instance.logger.LogMessage((object)("Setting next target to: " + currentTarget?.playerUsername)); } public void SetCurrentTargetToHost() { currentTargetIndex = 0; currentTarget = GetHostPlayer(); ControlCompanyPlugin.Instance.logger.LogMessage((object)"Setting next target to host"); } public void StartOfRoundInitialization() { gameStartedTime = 0f; SetCurrentTargetToHost(); ResetToDefault(); ControlCompanyPlugin.Instance.logger.LogMessage((object)"Start of round initialization completed."); } public void EndOfRoundCleanUp() { ResetToDefault(); ControlCompanyPlugin.Instance.logger.LogMessage((object)"End of round clean up completed."); } private void ResetToDefault() { GetHostPlayer().isTypingChat = false; currentMode = Mode.HOST; if ((Object)(object)ghost != (Object)null) { Object.Destroy((Object)(object)ghost); ghost = null; } if ((Object)(object)currentControlledEnemy != (Object)null) { currentControlledEnemy.DestroyAndCleanUp(); } EnableHostPlayer(enable: true); ControlCompanyPlugin.Instance.logger.LogMessage((object)"Reset to default."); } public PlayerControllerB GetHostPlayer() { return RoundManager.Instance.playersManager.allPlayerObjects[0].GetComponentInChildren<PlayerControllerB>(); } public List<PlayerControllerB> GetDeadPlayers() { return (from player in GetAllPlayers() where player.isPlayerDead select player).ToList(); } public List<PlayerControllerB> GetAlivePlayers() { return (from player in GetAllPlayers() where !player.isPlayerDead select player).ToList(); } public List<PlayerControllerB> GetAllPlayers() { List<PlayerControllerB> list = new List<PlayerControllerB>(); GameObject[] allPlayerObjects = RoundManager.Instance.playersManager.allPlayerObjects; for (int i = 0; i < allPlayerObjects.Length; i++) { PlayerControllerB componentInChildren = allPlayerObjects[i].GetComponentInChildren<PlayerControllerB>(); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.isPlayerControlled) { list.Add(componentInChildren); } } return list; } public bool DoesCurrentLevelExist() { return (Object)(object)GetCurrentLevel() != (Object)null; } public bool IsGameStarted() { if ((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)RoundManager.Instance.currentLevel != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null && GameNetworkManager.Instance.gameHasStarted && (Object)(object)StartOfRound.Instance != (Object)null) { return !StartOfRound.Instance.inShipPhase; } return false; } public SelectableLevel GetCurrentLevel() { return RoundManager.Instance.currentLevel; } public StartOfRound GetPlayersManager() { return RoundManager.Instance.playersManager; } private bool IsHost() { return ((NetworkBehaviour)RoundManager.Instance).IsHost; } public List<SpawnableItemWithRarity> GetSpawnableScraps() { return GetCurrentLevel().spawnableScrap; } public List<SpawnableEnemyWithRarity> GetSpawnableEnemies(bool isIndoor) { if (isIndoor) { return GetSpawnableIndoorEnemies(); } return GetSpawnableOutdoorEnemies(); } public List<SpawnableEnemyWithRarity> GetSpawnableIndoorEnemies() { if (!allowAllEnemies) { return GetAllowListedIndoorEnemies(); } return GetIndoorEnemyList(); } public List<SpawnableEnemyWithRarity> GetAllowListedIndoorEnemies() { return GetIndoorEnemyList().Where(delegate(SpawnableEnemyWithRarity enemy) { EnemyAI componentInChildren = enemy.enemyType.enemyPrefab.GetComponentInChildren<EnemyAI>(); return !((Object)(object)componentInChildren == (Object)null) && componentInChildren.IsEnemyAllowlisted(); }).ToList(); } public List<SpawnableEnemyWithRarity> GetIndoorEnemyList() { return GetCurrentLevel().Enemies; } public List<SpawnableEnemyWithRarity> GetSpawnableOutdoorEnemies() { if (!allowAllEnemies) { return GetAllowListedOutdoorEnemies(); } return GetOutdoorEnemyList(); } public List<SpawnableEnemyWithRarity> GetAllowListedOutdoorEnemies() { return GetOutdoorEnemyList().Where(delegate(SpawnableEnemyWithRarity enemy) { EnemyAI componentInChildren = enemy.enemyType.enemyPrefab.GetComponentInChildren<EnemyAI>(); return !((Object)(object)componentInChildren == (Object)null) && componentInChildren.IsEnemyAllowlisted(); }).ToList(); } public List<SpawnableEnemyWithRarity> GetOutdoorEnemyList() { return GetCurrentLevel().OutsideEnemies; } private GameObject SpawnScrap(SpawnableItemWithRarity scrap, Vector3 position) { //IL_000b: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(scrap.spawnableItem.spawnPrefab, position, Quaternion.identity); GrabbableObject componentInChildren = obj.GetComponentInChildren<GrabbableObject>(); ((Component)componentInChildren).transform.rotation = Quaternion.Euler(componentInChildren.itemProperties.restingRotation); obj.GetComponentInChildren<NetworkObject>().Spawn(true); return obj; } private GameObject SpawnEnemy(SpawnableEnemyWithRarity enemyWithRarity, Vector3 position) { //IL_000b: 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_0025: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(enemyWithRarity.enemyType.enemyPrefab, position + new Vector3(0f, 0.5f, 0f), Quaternion.identity); obj.GetComponentInChildren<NetworkObject>().Spawn(true); return obj; } private EnemyController SpawnControllableEnemy(SpawnableEnemyWithRarity enemyWithRarity, Vector3 position, Quaternion rotation) { //IL_000b: 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_0025: 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_0047: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(enemyWithRarity.enemyType.enemyPrefab, position + new Vector3(0f, 0.5f, 0f), Quaternion.identity); val.GetComponentInChildren<NetworkObject>().Spawn(true); GameObject val2 = new GameObject("enemy_controller"); val2.transform.position = position + new Vector3(0f, 0.5f, 0f); val2.transform.rotation = rotation; EnemyAI componentInChildren = val.GetComponentInChildren<EnemyAI>(); if ((Object)(object)componentInChildren == (Object)null) { throw new Exception("Enemy AI is null, cannot spawn enemy"); } EnemyController andAttachEnemyController = componentInChildren.GetAndAttachEnemyController(val2); andAttachEnemyController.InitializeEnemyController(GetHostPlayer().playerActions, val); andAttachEnemyController.EnableLight(IsTargetInside()); return andAttachEnemyController; } private DissonanceComms GetMic() { return StartOfRound.Instance.voiceChatModule; } private void ForceMicPushToTalk() { IngamePlayerSettings.Instance.settings.pushToTalk = true; } private void ResetMicPushToTalk() { IngamePlayerSettings.Instance.settings.pushToTalk = initialMicPushToTalkSetting; } } internal class DoorOpener : MonoBehaviour { public void OpenDoor(float range) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, range); for (int i = 0; i < array.Length; i++) { DoorLock componentInChildren = ((Component)array[i]).GetComponentInChildren<DoorLock>(); if ((Object)(object)componentInChildren != (Object)null && !componentInChildren.GetFieldValue<bool>("isDoorOpened")) { if (componentInChildren.isLocked) { componentInChildren.UnlockDoorServerRpc(); } componentInChildren.OpenDoorAsEnemyServerRpc(); ((Component)componentInChildren).gameObject.GetComponent<AnimatedObjectTrigger>().TriggerAnimationNonPlayer(false, true, false); ControlCompanyPlugin.Instance.logger.LogMessage((object)"Opened door"); } } } } internal class EnemyController : CustomPlayerController { protected GameObject enemyGameObject; private EnemyAI enemyAI; private NavMeshAgent enemyAIAgent; private float originalAgentAngularSpeed; private float originalAgentSpeed; private float rotationSpeed = 5f; protected bool isAIControlled; protected bool controlEnemyRotation; protected bool controlEnemyMovement = true; protected bool lockEnemyRotationInput; public bool IsAIControlled => isAIControlled; public EnemyAI EnemyAI => enemyAI; public virtual void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!isInitialized) { Initialize(playerActions, CameraMode.THIRD_PERSON); enemyAI = GetEnemyAIFromEnemyGameObject(enemyGameObject); if ((Object)(object)enemyAI == (Object)null) { throw new Exception("Enemy gameobject does not have EnemyAI script attacked."); } canJump = false; ((Component)enemyAI).gameObject.LogLayer(); enemyGameObject.transform.position = ((Component)this).transform.position; enemyGameObject.transform.rotation = ((Component)this).transform.rotation; this.enemyGameObject = enemyGameObject; enemyAIAgent = enemyGameObject.GetComponentInChildren<NavMeshAgent>(); originalAgentAngularSpeed = enemyAIAgent.angularSpeed; originalAgentSpeed = enemyAIAgent.speed; ConfigureEnemyAttributes(enemyAI); EnableAIControl(enabled: false); } } protected EnemyAI GetEnemyAIFromEnemyGameObject(GameObject enemyObj) { return enemyObj.GetComponentInChildren<EnemyAI>(); } private void ConfigureEnemyAttributes(EnemyAI enemyAI) { EnemyAttributes enemyAttributes = enemyAI.GetEnemyAttributes(); base.WalkSpeed = enemyAttributes.WalkSpeed; base.RunSpeed = enemyAttributes.RunSpeed; SetCamDistance(enemyAttributes.CamDistance); SetCamHeight(enemyAttributes.CamHeight); controlEnemyRotation = enemyAttributes.PlayerControlsRotation; controlEnemyMovement = true; } protected override void Update() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) if (!isInitialized) { return; } base.Update(); if (!isAIControlled) { if (!enemyAI.isEnemyDead) { if (controlEnemyMovement) { enemyGameObject.transform.position = ((Component)this).transform.position; } if (controlEnemyRotation && !lockEnemyRotationInput) { enemyGameObject.transform.rotation = ((Component)this).transform.rotation; } } } else { ((Component)this).transform.position = enemyGameObject.transform.position; } } public void SetLockEnemyRotation(bool lockEnemyRotationInput) { this.lockEnemyRotationInput = lockEnemyRotationInput; } public virtual void UsePrimarySkill() { CheckInitialized(); _ = isAIControlled; } public virtual void ReleasePrimarySkill() { CheckInitialized(); _ = isAIControlled; } public virtual void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { enemyAI.SwitchToBehaviourState(1); } } public virtual void ReleaseSecondarySkill() { CheckInitialized(); _ = isAIControlled; } public void SwitchAIState(int stateIndex) { CheckInitialized(); if (!isAIControlled) { enemyAI.SwitchToBehaviourState(stateIndex); } } protected virtual void EnableAIControl(bool enabled) { CheckInitialized(); isAIControlled = enabled; ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Enable AI control: {enabled}"); if (IsAIControlled) { enemyAIAgent.angularSpeed = originalAgentAngularSpeed; enemyAIAgent.speed = originalAgentSpeed; enemyAIAgent.isStopped = false; } else { enemyAI.ChangeOwnershipOfEnemy(ControlCenter.Instance.GetHostPlayer().actualClientId); enemyAIAgent.angularSpeed = 0f; enemyAIAgent.speed = 0f; enemyAIAgent.isStopped = true; ((Component)this).transform.SetParent((Transform)null); } canMove = !isAIControlled; } public void ToggleAIControl() { CheckInitialized(); isAIControlled = !isAIControlled; EnableAIControl(isAIControlled); } public virtual void DestroyAndCleanUp() { if (!enemyAI.isEnemyDead) { Object.Destroy((Object)(object)enemyGameObject); } Object.Destroy((Object)(object)((Component)this).gameObject); } public virtual string GetPrimarySkillName() { return ""; } public virtual string GetSecondarySkillName() { return "Secondary Skill"; } protected void CheckInitialized() { if (!isInitialized) { throw new Exception("Not initialized yet."); } } } internal class CustomPlayerController : MonoBehaviour { public enum CameraMode { THIRD_PERSON, FIRST_PERSON } protected bool isInitialized; protected bool hasControl; protected bool canMove; protected bool canRotate; protected bool canJump; protected CameraMode camMode; protected CharacterController characterController; protected GameObject cameraGameObjectParent; protected GameObject cameraGameObject; protected Camera camera; protected Light light; protected PlayerActions playerActions; protected DoorOpener doorOpener; private float runSpeed = 9f; private float walkSpeed = 7f; private float camDistance = -3.5f; private float camHeight = 2f; private float gravity = -20f; private float jumpHeight = 4.5f; private float currentYVelocity; private HashSet<int> seenLayers = new HashSet<int>(); public float RunSpeed { get { return runSpeed; } set { runSpeed = value; } } public float WalkSpeed { get { return walkSpeed; } set { walkSpeed = value; } } public float Gravity { get { return gravity; } set { gravity = value; } } public void Initialize(PlayerActions playerActions, CameraMode camMode) { if (!isInitialized) { this.playerActions = playerActions; this.camMode = camMode; characterController = InitializeCharacterController(); camera = InitializeCamera(); light = InitializeLight(((Component)camera).gameObject); doorOpener = ((Component)this).gameObject.AddComponent<DoorOpener>(); EnableControl(enable: true); isInitialized = true; } } public void EnableLight(bool enable) { ((Behaviour)light).enabled = enable; } public void EnableControl(bool enable) { hasControl = enable; canMove = enable; canRotate = enable; canJump = enable; } public bool IsMoving() { //IL_0006: 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) Vector3 velocity = characterController.velocity; return ((Vector3)(ref velocity)).sqrMagnitude > 0f; } public void SetCamHeight(float camHeight) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) this.camHeight = camHeight; cameraGameObjectParent.transform.localPosition = new Vector3(0f, camHeight, 0f); } public void SetCamDistance(float camDistance) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) this.camDistance = camDistance; cameraGameObject.transform.localPosition = new Vector3(0f, 0f, (camMode == CameraMode.THIRD_PERSON) ? camDistance : 0f); } protected virtual void Update() { if (isInitialized && hasControl) { if (canMove) { Move(); } if (canRotate) { Rotate(); } if (((ButtonControl)InputKeys.CONTROLLER_USE_KEY).wasPressedThisFrame) { doorOpener.OpenDoor(3f); } } } protected virtual void Move() { //IL_0006: 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_0020: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_0044: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) MovementActions movement = playerActions.Movement; bool flag = ((MovementActions)(ref movement)).Sprint.IsInProgress(); movement = playerActions.Movement; Vector3 val = Vector2.op_Implicit(((MovementActions)(ref movement)).Move.ReadValue<Vector2>()); Vector3 val2 = ((Component)this).transform.right * val.x; Vector3 val3 = ((Component)this).transform.forward * val.y; bool isGrounded = characterController.isGrounded; if (isGrounded && currentYVelocity < 0f) { currentYVelocity = 0f; } if (canJump && isGrounded && ((ButtonControl)InputKeys.CONTROLLER_JUMP_KEY).wasPressedThisFrame) { currentYVelocity += Mathf.Sqrt(jumpHeight * (0f - gravity)); } currentYVelocity += gravity * Time.deltaTime; characterController.Move(((val2 + val3) * (flag ? runSpeed : walkSpeed) + new Vector3(0f, currentYVelocity, 0f)) * Time.deltaTime); } protected virtual void Rotate() { //IL_0006: 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_0013: 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_0032: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0095: Unknown result type (might be due to invalid IL or missing references) MovementActions movement = playerActions.Movement; Vector2 val = ((MovementActions)(ref movement)).Look.ReadValue<Vector2>() * 0.008f * (float)IngamePlayerSettings.Instance.settings.lookSensitivity; if (IngamePlayerSettings.Instance.settings.invertYAxis) { val.y *= -1f; } ((Component)this).transform.Rotate(new Vector3(0f, val.x, 0f)); cameraGameObjectParent.transform.Rotate(new Vector3(0f - val.y, 0f, 0f)); } private Light InitializeLight(GameObject lightParent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("controller_light"); val.transform.SetParent(lightParent.transform); val.transform.localPosition = new Vector3(0f, 0.5f, 0f); val.transform.localRotation = Quaternion.identity; Light obj = val.AddComponent<Light>(); obj.range = 15f; obj.intensity = 250f; obj.cullingMask = -1; return obj; } private CharacterController InitializeCharacterController() { //IL_000c: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) CharacterController obj = ((Component)this).gameObject.AddComponent<CharacterController>(); ((Collider)obj).excludeLayers = LayerMask.op_Implicit(LayerMask.op_Implicit(Constants.PLAYER_LOS_LAYER) | LayerMask.op_Implicit(Constants.ITERACTABLE_OBJ_LAYER) | LayerMask.op_Implicit(Constants.ENEMIES_LAYER) | LayerMask.op_Implicit(Constants.PROPS_LAYER) | LayerMask.op_Implicit(Constants.PLAYER_RAGDOLL_LAYER)); obj.center = new Vector3(0f, 0.55f, 0f); obj.height = 0.4f; obj.slopeLimit = 60f; obj.stepOffset = 0.4f; return obj; } private Camera InitializeCamera() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("controller_cam_parent"); val.transform.SetParent(((Component)this).transform); val.transform.localRotation = Quaternion.identity; val.transform.localPosition = new Vector3(0f, camHeight, 0f); GameObject val2 = new GameObject("controller_cam"); val2.transform.SetParent(val.transform); val2.transform.localRotation = Quaternion.identity; val2.transform.localPosition = new Vector3(0f, 0f, (camMode == CameraMode.THIRD_PERSON) ? camDistance : 0f); Camera obj = val2.AddComponent<Camera>(); val2.AddComponent<AudioListener>(); cameraGameObject = val2; cameraGameObjectParent = val; obj.cullingMask = ControlCenter.Instance.GetHostPlayer().gameplayCamera.cullingMask; return obj; } private void OnControllerColliderHit(ControllerColliderHit hit) { if (!seenLayers.Contains(hit.gameObject.layer)) { hit.gameObject.LogLayer(); seenLayers.Add(hit.gameObject.layer); } } } } namespace ControlCompany.Core.UI { public class UIInstruction { public string InputKey { get; set; } public string ActionText { get; set; } } internal class UIManager : MonoBehaviour { private const float GUI_LABEL_HEIGHT = 36f; private const float GUI_LABEL_WIDTH = 750f; private const float GUI_PADDING = 32f; private const int GUI_FONT_SIZE = 28; private const FontStyle GUI_FONT_WEIGHT = 0; public static UIManager Instance; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } } public void RenderNotHostLabel(string toggleUIKey) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 24, fontStyle = (FontStyle)0 }; val.normal.textColor = Color.red; RenderTextTopLeftCorner("Not hosting. ControlCompany mod is disabled. Press " + toggleUIKey + " to hide.", 0f, val); } public void RenderEnemyControls(string primaryKey, string secondaryKey, string aiControlKey, string exitKey, EnemyController enemyController, PlayerControllerB hostPlayer) { string primarySkillName = enemyController.GetPrimarySkillName(); string secondarySkillName = enemyController.GetSecondarySkillName(); List<UIInstruction> list = new List<UIInstruction>(); if (enemyController.IsAIControlled) { list.Add(new UIInstruction { InputKey = aiControlKey, ActionText = "Take control" }); } else { if (!Utility.IsNullOrWhiteSpace(primarySkillName)) { list.Add(new UIInstruction { InputKey = primaryKey, ActionText = primarySkillName }); } if (!Utility.IsNullOrWhiteSpace(secondarySkillName)) { list.Add(new UIInstruction { InputKey = secondaryKey, ActionText = secondarySkillName }); } list.Add(new UIInstruction { InputKey = aiControlKey, ActionText = "AI control" }); } list.Add(new UIInstruction { InputKey = exitKey, ActionText = "Exit" }); RenderPlayerStatus(hostPlayer); float height = 0f; height = RenderEnemyStatus(enemyController, height); RenderEnemySkills(list, height); } public void RenderHostControls(string ghostModeKey, string cycleLeftKey, string cycleRightKey, PlayerControllerB currentTarget, bool isExtendedModeEnabled, string creditsKey, string entranceTeleportKey, string toggleUIKey) { List<UIInstruction> list = new List<UIInstruction>(); list.Add(new UIInstruction { InputKey = ghostModeKey, ActionText = "Ghost mode" }); list.Add(new UIInstruction { InputKey = $"{cycleLeftKey}/{cycleRightKey}", ActionText = "Change target" }); list.Add(new UIInstruction { InputKey = toggleUIKey, ActionText = "Hide UI" }); if (isExtendedModeEnabled) { list.Add(new UIInstruction { InputKey = creditsKey, ActionText = "Give credits" }); list.Add(new UIInstruction { InputKey = entranceTeleportKey, ActionText = "Teleport to entrance" }); } RenderHostControlList(list, currentTarget); } public void RenderGhostControls(List<string> enemySpawnKeys, string exitKey, List<SpawnableEnemyWithRarity> enemies, List<SpawnableItemWithRarity> scraps, PlayerControllerB hostPlayer, bool scrapSpawnMode) { List<UIInstruction> list = new List<UIInstruction>(); if (!scrapSpawnMode) { for (int i = 0; i < enemies.Count && i < enemySpawnKeys.Count; i++) { EnemyAI componentInChildren = enemies[i].enemyType.enemyPrefab.GetComponentInChildren<EnemyAI>(); list.Add(new UIInstruction { InputKey = enemySpawnKeys[i], ActionText = $"Control {(((Object)(object)componentInChildren == (Object)null) ? enemies[i].enemyType.enemyName : componentInChildren.GetEnemyName())}" }); } } else { for (int j = 0; j < scraps.Count && j < enemySpawnKeys.Count; j++) { list.Add(new UIInstruction { InputKey = enemySpawnKeys[j], ActionText = $"Spawn {scraps[j].spawnableItem.itemName}" }); } } list.Add(new UIInstruction { InputKey = exitKey, ActionText = "Exit" }); RenderPlayerStatus(hostPlayer); RenderGhostControlList(list); } private void RenderGhostControlList(List<UIInstruction> ghostControls) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown if (ghostControls.Count <= 0) { return; } GUIStyle style = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)5, fontSize = 28, fontStyle = (FontStyle)0 }; float num = 0f; foreach (UIInstruction ghostControl in ghostControls) { RenderTextTopRightCorner($"{ghostControl.InputKey}: {ghostControl.ActionText}", num, style); num += 36f; } } private float RenderMicStatus(float height, PlayerControllerB hostPlayer) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 28, fontStyle = (FontStyle)0 }; float num = height; if (IngamePlayerSettings.Instance.settings.micEnabled) { if (!StartOfRound.Instance.voiceChatModule.IsMuted) { val.normal.textColor = Color.green; RenderTextTopLeftCorner(string.Format("{0} mic enabled", hostPlayer.isPlayerDead ? "Dead" : "Player"), num, val); } else { val.normal.textColor = Color.red; RenderTextTopLeftCorner(string.Format("{0} mic disabled (push to talk)", hostPlayer.isPlayerDead ? "Dead" : "Player"), num, val); } num += 36f; } return num; } private float RenderPlayerStatus(PlayerControllerB hostPlayer) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00d8: 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) GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 28, fontStyle = (FontStyle)0 }; if (hostPlayer.isPlayerDead) { val.normal.textColor = Color.red; } else { val.normal.textColor = Color.green; } float num = 0f; RenderTextTopLeftCorner(string.Format("Player status: {0}", hostPlayer.isPlayerDead ? "Dead" : "Alive"), num, val); num += 36f; if (!hostPlayer.isPlayerDead) { GUIStyle val2 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)3, fontSize = 28, fontStyle = (FontStyle)0 }; bool flag = !HostIsNearOtherPlayers(hostPlayer); if (flag) { val2.normal.textColor = Color.green; } else { val2.normal.textColor = Color.red; } RenderTextTopLeftCorner(string.Format("Player proximity: {0}", flag ? "Alone" : "Near others"), num, val2); num += 36f; } return num + RenderMicStatus(num, hostPlayer); } private void RenderHostControlList(List<UIInstruction> hostControls, PlayerControllerB currentTarget) { //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_0022: 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_0032: Expected O, but got Unknown if (hostControls.Count <= 0) { return; } GUIStyle style = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)5, fontSize = 28, fontStyle = (FontStyle)0 }; float num = 0f; if ((Object)(object)currentTarget != (Object)null) { RenderTextTopRightCorner($"Spawn target: {currentTarget.playerUsername}", num, style); num += 36f; } foreach (UIInstruction hostControl in hostControls) { RenderTextTopRightCorner($"{hostControl.InputKey}: {hostControl.ActionText}", num, style); num += 36f; } } private float RenderEnemyStatus(EnemyController enemyController, float height) { //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) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) float num = height; if (enemyController.IsAIControlled) { GUIStyle val = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)5, fontSize = 28, fontStyle = (FontStyle)0 }; val.normal.textColor = Color.red; RenderTextTopRightCorner("AI controlled", num, val); num += 36f; } return num; } private float RenderEnemySkills(List<UIInstruction> playerEnemyControls, float height) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown float num = height; if (playerEnemyControls.Count > 0) { GUIStyle style = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)5, fontSize = 28, fontStyle = (FontStyle)0 }; foreach (UIInstruction playerEnemyControl in playerEnemyControls) { RenderTextTopRightCorner($"{playerEnemyControl.InputKey}: {playerEnemyControl.ActionText}", num, style); num += 36f; } } return num; } private void RenderTextMiddle(string text, float yPos, GUIStyle style) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect((float)Screen.width / 2f - 375f, yPos + 32f, 750f, 36f), text, style); } private void RenderTextTopRightCorner(string text, float yPos, GUIStyle style) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect((float)Screen.width - 750f - 32f, yPos + 32f, 750f, 36f), text, style); } private void RenderTextTopLeftCorner(string text, float yPos, GUIStyle style) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect(32f, yPos + 32f, 750f, 36f), text, style); } private bool HostIsNearOtherPlayers(PlayerControllerB hostPlayer) { return (bool)hostPlayer.Call("NearOtherPlayers", hostPlayer, 17f); } } } namespace ControlCompany.Core.Input { public static class InputKeys { public static KeyControl EXIT_KEY = Keyboard.current.escapeKey; public static KeyControl EXTENDED_MODE_KEY = Keyboard.current.digit0Key; public static KeyControl TOGGLE_UI_KEY = Keyboard.current.uKey; public static KeyControl HOST_GHOST_MODE_KEY = Keyboard.current.f1Key; public static KeyControl HOST_CYCLE_PLAYER_TARGET_LIST_KEY_LEFT = Keyboard.current.oKey; public static KeyControl HOST_CYCLE_PLAYER_TARGET_LIST_KEY_RIGHT = Keyboard.current.pKey; public static KeyControl HOST_GIVE_CREDITS_KEY = Keyboard.current.digit8Key; public static KeyControl HOST_TELEPORT_TO_ENTRANCE_KEY = Keyboard.current.digit9Key; public static KeyControl GHOST_SPAWN_ENEMY_1 = Keyboard.current.f1Key; public static KeyControl GHOST_SPAWN_ENEMY_2 = Keyboard.current.f2Key; public static KeyControl GHOST_SPAWN_ENEMY_3 = Keyboard.current.f3Key; public static KeyControl GHOST_SPAWN_ENEMY_4 = Keyboard.current.f4Key; public static KeyControl GHOST_SPAWN_ENEMY_5 = Keyboard.current.f5Key; public static KeyControl GHOST_SPAWN_ENEMY_6 = Keyboard.current.f6Key; public static KeyControl GHOST_SPAWN_ENEMY_7 = Keyboard.current.f7Key; public static KeyControl GHOST_SPAWN_ENEMY_8 = Keyboard.current.f8Key; public static KeyControl GHOST_SPAWN_ENEMY_9 = Keyboard.current.f9Key; public static KeyControl GHOST_SPAWN_ENEMY_10 = Keyboard.current.f10Key; public static KeyControl GHOST_SPAWN_ENEMY_11 = Keyboard.current.f11Key; public static KeyControl GHOST_SPAWN_ENEMY_12 = Keyboard.current.f12Key; public static List<KeyControl> GHOST_SPAWN_ENEMY_KEYS = new List<KeyControl>(); public static KeyControl ENEMY_TOGGLE_AI_KEY = Keyboard.current.f1Key; public static ButtonControl ENEMY_PRIMARY_SKILL_BUTTON = Mouse.current.leftButton; public static ButtonControl ENEMY_SECONDARY_SKILL_BUTTON = Mouse.current.rightButton; public static KeyControl LOCK_ENEMY_ROTATION_KEY = Keyboard.current.leftAltKey; public static KeyControl CONTROLLER_USE_KEY = Keyboard.current.eKey; public static KeyControl CONTROLLER_JUMP_KEY = Keyboard.current.spaceKey; } } namespace ControlCompany.Core.Extentions { public static class ExtensionMethods { public static T GetFieldValue<T>(this object obj, string name) { return (T)(obj.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj)); } public static void SetFieldValue<T>(this object obj, string method, T value) { obj.GetType().GetField(method, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.SetField | BindingFlags.SetProperty)?.SetValue(obj, value); } public static object Call(this object o, string methodName, params object[] args) { MethodInfo method = o.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic); if (method != null) { return method.Invoke(o, args); } return null; } public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue) { if (dictionary.TryGetValue(key, out var value)) { return value; } return defaultValue; } public static IEnumerable<IEnumerable<T>> Chunk<T>(this IEnumerable<T> source, int chunksize) { while (source.Any()) { yield return source.Take(chunksize); source = source.Skip(chunksize); } } public static void LogLayer(this GameObject gameObject) { ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Enemy layer ({LayerMask.LayerToName(gameObject.layer)}): {gameObject.layer}"); } public static void LogGameObjectName(this GameObject gameObject) { ControlCompanyPlugin.Instance.logger.LogMessage((object)string.Format("GameObject name: {0}, parent: {1}", ((Object)gameObject).name, ((Object)(object)gameObject.transform.parent != (Object)null) ? ((Object)gameObject.transform.parent).name : "null")); } public static void LogAllComponents(this GameObject gameObject) { Component[] components = gameObject.GetComponents<Component>(); foreach (Component val in components) { _ = $"GameObject ({((Object)gameObject).name}) component: {((Object)val).name}"; } } public static void LogPosition(this GameObject gameObject) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ControlCompanyPlugin.Instance.logger.LogMessage((object)$"GameObject ({((Object)gameObject).name}) position: {gameObject.transform.position}, local position: {gameObject.transform.localPosition}"); } } } namespace ControlCompany.Core.Enemy { internal class CentipedeEnemyController : EnemyController { private CentipedeAI centipedeAI; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown centipedeAI = (CentipedeAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } protected override void Update() { base.Update(); bool flag = IsClingingToSomething(); controlEnemyRotation = !flag; controlEnemyMovement = !flag; } protected override void Move() { if (!IsClingingToSomething()) { base.Move(); } } public override void UsePrimarySkill() { CheckInitialized(); if (!isAIControlled && ((EnemyAI)centipedeAI).currentBehaviourStateIndex == 1) { SwitchAIState(2); } } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled && !IsClingingToSomething()) { centipedeAI.Call("RaycastToCeiling"); SwitchAIState(1); } } public bool IsClingingToSomething() { if (!((Object)(object)centipedeAI.clingingToPlayer != (Object)null) && !((EnemyAI)centipedeAI).inSpecialAnimation && !centipedeAI.GetFieldValue<bool>("clingingToDeadBody") && !centipedeAI.GetFieldValue<bool>("clingingToCeiling") && !centipedeAI.GetFieldValue<bool>("startedCeilingAnimationCoroutine")) { return centipedeAI.GetFieldValue<bool>("inDroppingOffPlayerAnim"); } return true; } public override string GetPrimarySkillName() { return "Drop"; } public override string GetSecondarySkillName() { return "Attach to ceiling"; } } internal class FlowermanEnemyController : EnemyController { private FlowermanAI flowermanAI; private const int FLOWERMAN_DEFAULT_MODE = 0; private const int FLOWERMAN_STAND_MODE = 1; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown flowermanAI = (FlowermanAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { ((EnemyAI)flowermanAI).SwitchToBehaviourState(1); } } public override void ReleaseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { ((EnemyAI)flowermanAI).SwitchToBehaviourState(0); } } public override void UsePrimarySkill() { CheckInitialized(); if (!isAIControlled && flowermanAI.carryingPlayerBody) { flowermanAI.Call("DropPlayerBody"); flowermanAI.DropPlayerBodyServerRpc(); } } public override string GetPrimarySkillName() { if (!flowermanAI.carryingPlayerBody) { return ""; } return "Drop body"; } public override string GetSecondarySkillName() { return ""; } } internal class ForestGiantEnemyController : EnemyController { private ForestGiantAI forestGiantAI; private const int FOREST_GIANT_DEFAULT_MODE = 0; private const int FOREST_GIANT_CHASE_MODE = 1; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown forestGiantAI = (ForestGiantAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } protected override void Update() { base.Update(); bool flag = IsEatingPlayer(); controlEnemyRotation = !flag; controlEnemyMovement = !flag; } protected override void Move() { if (!IsEatingPlayer()) { base.Move(); } } public override void UseSecondarySkill() { CheckInitialized(); _ = isAIControlled; } public override void ReleaseSecondarySkill() { CheckInitialized(); _ = isAIControlled; } public override string GetSecondarySkillName() { return ""; } public bool IsEatingPlayer() { return forestGiantAI.GetFieldValue<bool>("inEatingPlayerAnimation"); } } internal class HoardingBugEnemyController : EnemyController { private HoarderBugAI hoarderBugAI; private List<Type> allowedGrabbableItemUse = new List<Type> { typeof(ShotgunItem), typeof(NoisemakerProp), typeof(FlashlightItem) }; private float grabRange = 1.5f; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown hoarderBugAI = (HoarderBugAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } protected override void EnableAIControl(bool enabled) { //IL_003c: 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) if (enabled) { hoarderBugAI.Call("ChooseNestPosition"); ((EnemyAI)hoarderBugAI).SwitchToBehaviourState(0); } else { hoarderBugAI.nestPosition = new Vector3(2000f, 2000f, 2000f); } base.EnableAIControl(enabled); } protected override void Update() { //IL_002c: 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 (isInitialized) { base.Update(); if (!isAIControlled) { hoarderBugAI.nestPosition = new Vector3(2000f, 2000f, 2000f); } } } public override void UsePrimarySkill() { CheckInitialized(); if (!isAIControlled && hoarderBugAI.heldItem != null) { UseHeldItem(); } } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { ControlCompanyPlugin.Instance.logger.LogMessage((object)"Using hoarder bug secondary"); if (hoarderBugAI.heldItem == null) { GrabNearbyItem(); } else { DropCurrentItem(); } } } public void UseHeldItem() { //IL_003a: 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_004f: Unknown result type (might be due to invalid IL or missing references) GrabbableObject itemGrabbableObject = hoarderBugAI.heldItem.itemGrabbableObject; Type type = ((object)itemGrabbableObject).GetType(); if (allowedGrabbableItemUse.Contains(type)) { if (type == typeof(ShotgunItem)) { ShotgunItem val = (ShotgunItem)itemGrabbableObject; val.gunShootAudio.volume = 0.15f; val.shotgunRayPoint = enemyGameObject.transform; val.ShootGunAndSync(false); } else { itemGrabbableObject.UseItemOnClient(true); } } } public void GrabNearbyItem() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (hoarderBugAI.heldItem != null) { return; } Collider[] array = Physics.OverlapSphere(enemyGameObject.transform.position, grabRange); for (int i = 0; i < array.Length; i++) { GrabbableObject componentInChildren = ((Component)array[i]).GetComponentInChildren<GrabbableObject>(); if ((Object)(object)componentInChildren != (Object)null && hoarderBugAI.heldItem == null && (Object)(object)((Component)componentInChildren).GetComponent<NetworkObject>() != (Object)null) { hoarderBugAI.targetItem = componentInChildren; hoarderBugAI.Call("GrabTargetItemIfClose"); break; } } } public void DropCurrentItem() { if (hoarderBugAI.heldItem != null) { hoarderBugAI.Call("DropItemAndCallDropRPC", ((Component)hoarderBugAI.heldItem.itemGrabbableObject).GetComponent<NetworkObject>(), false); } } public override string GetPrimarySkillName() { if (hoarderBugAI.heldItem == null || !allowedGrabbableItemUse.Contains(((object)hoarderBugAI.heldItem).GetType())) { return ""; } return "Use item"; } public override string GetSecondarySkillName() { if (hoarderBugAI.heldItem != null) { return "Drop item"; } return "Grab item"; } } internal class JesterEnemyController : EnemyController { private JesterAI jesterEnemyAI; private const int JESTER_DEFAULT_MODE = 0; private const int JESTER_CRANK_MODE_INDEX = 1; private const int JESTER_POP_OUT_INDEX = 2; private float initialWalkSpeed; private float initialRunSpeed; private bool initialControlRotation; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown jesterEnemyAI = (JesterAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); initialWalkSpeed = base.WalkSpeed; initialRunSpeed = base.RunSpeed; initialControlRotation = controlEnemyRotation; } protected override void Update() { base.Update(); if (IsCranking()) { controlEnemyMovement = false; controlEnemyRotation = false; } else if (IsPoppedOut() || IsInBox()) { controlEnemyMovement = initialControlRotation; controlEnemyRotation = initialControlRotation; } if (IsPoppedOut()) { base.WalkSpeed = 10f; base.RunSpeed = 15f; } else if (IsInBox()) { base.WalkSpeed = initialWalkSpeed; base.RunSpeed = initialRunSpeed; } } public override void UsePrimarySkill() { CheckInitialized(); if (!isAIControlled && !IsInBox()) { ResetState(); } } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled && IsInBox()) { Cranking(); } } public override void ReleaseSecondarySkill() { CheckInitialized(); if (!isAIControlled && IsCranking()) { PopOut(); } } protected override void Move() { if (!IsCranking()) { base.Move(); } } public override string GetPrimarySkillName() { return "Close box"; } public override string GetSecondarySkillName() { return "(HOLD) Play music"; } private void Cranking() { SwitchAIState(1); } private void PopOut() { SwitchAIState(2); } private void ResetState() { SwitchAIState(0); } private bool IsInBox() { return ((EnemyAI)jesterEnemyAI).currentBehaviourStateIndex == 0; } private bool IsCranking() { return ((EnemyAI)jesterEnemyAI).currentBehaviourStateIndex == 1; } private bool IsPoppedOut() { return ((EnemyAI)jesterEnemyAI).currentBehaviourStateIndex == 2; } } internal class MouthDogEnemyController : EnemyController { private MouthDogAI mouthDogAI; private const int MOUTH_DOG_LUNGE = 2; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown mouthDogAI = (MouthDogAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled && !IsLunging()) { Lunge(); } } public override string GetSecondarySkillName() { return "Lunge"; } private void Lunge() { ((EnemyAI)mouthDogAI).SwitchToBehaviourState(2); } private bool IsLunging() { return ((EnemyAI)mouthDogAI).currentBehaviourStateIndex == 2; } } internal class NutcrackerEnemyController : EnemyController { private NutcrackerEnemyAI nutcrackerEnemyAI; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown nutcrackerEnemyAI = (NutcrackerEnemyAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } protected override void Update() { if (isInitialized) { base.Update(); if (!isAIControlled && IsMoving() && ((EnemyAI)nutcrackerEnemyAI).currentBehaviourStateIndex != 0) { ((EnemyAI)nutcrackerEnemyAI).SwitchToBehaviourState(0); } } } public override void UsePrimarySkill() { CheckInitialized(); if (!isAIControlled && (Object)(object)nutcrackerEnemyAI.gun != (Object)null) { nutcrackerEnemyAI.gun.gunShootAudio.volume = 0.15f; nutcrackerEnemyAI.FireGunServerRpc(); } } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { SwitchAIState(1); } } public override void ReleaseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { SwitchAIState(0); } } public override void DestroyAndCleanUp() { if (!((EnemyAI)nutcrackerEnemyAI).isEnemyDead) { Object.Destroy((Object)(object)((Component)nutcrackerEnemyAI.gun).gameObject); } base.DestroyAndCleanUp(); } public override string GetPrimarySkillName() { return "Fire"; } public override string GetSecondarySkillName() { return "(HOLD) Sentry mode"; } } internal class PufferEnemyController : EnemyController { private PufferAI pufferAI; public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown pufferAI = (PufferAI)GetEnemyAIFromEnemyGameObject(enemyGameObject); base.InitializeEnemyController(playerActions, enemyGameObject); } public override void UsePrimarySkill() { CheckInitialized(); if (!isAIControlled) { if (((EnemyAI)pufferAI).currentBehaviourStateIndex != 1) { SwitchAIState(1); } pufferAI.StompServerRpc(); } } public override void UseSecondarySkill() { CheckInitialized(); if (!isAIControlled) { if (((EnemyAI)pufferAI).currentBehaviourStateIndex != 1) { SwitchAIState(1); } pufferAI.ShakeTailServerRpc(); } } public override string GetPrimarySkillName() { return "Stomp"; } public override string GetSecondarySkillName() { return "Smoke"; } } } namespace ControlCompany.Core.Config { internal class ConfigManager : MonoBehaviour { public static ConfigManager Instance; private ConfigFile config; private bool isInitialized; private const string KEYBIND_CONFIG = "Keybinds"; private const string KEYBIND_CONFIG_HOST_MODE = "Keybinds.PlayerMode"; private const string KEYBIND_CONFIG_GHOST_MODE = "Keybinds.GhostMode"; private const string KEYBIND_CONFIG_ENEMY_MODE = "Keybinds.MonsterMode"; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } } public void Initialize(ConfigFile config) { if (!isInitialized) { this.config = config; isInitialized = true; } } public void LoadPlayerKeybinds() { if (config != null) { LoadKeysFromConfig(config); } } private void LoadKeysFromConfig(ConfigFile config) { ConfigEntry<string> keyEntry = config.Bind<string>("Keybinds", "extended_mode_key", "0", (ConfigDescription)null); ConfigEntry<string> keyEntry2 = config.Bind<string>("Keybinds", "exit_mode_key", "esc", (ConfigDescription)null); ConfigEntry<string> keyEntry3 = config.Bind<string>("Keybinds", "open_door", "e", (ConfigDescription)null); ConfigEntry<string> keyEntry4 = config.Bind<string>("Keybinds", "toggle_ui", "u", (ConfigDescription)null); InputKeys.CONTROLLER_USE_KEY = GetKeyControlFromConfig(keyEntry3, InputKeys.CONTROLLER_USE_KEY); InputKeys.EXTENDED_MODE_KEY = GetKeyControlFromConfig(keyEntry, InputKeys.EXTENDED_MODE_KEY); InputKeys.EXIT_KEY = GetKeyControlFromConfig(keyEntry2, InputKeys.EXIT_KEY); InputKeys.TOGGLE_UI_KEY = GetKeyControlFromConfig(keyEntry4, InputKeys.TOGGLE_UI_KEY); ConfigEntry<string> keyEntry5 = config.Bind<string>("Keybinds.PlayerMode", "ghost_mode_key", "f1", (ConfigDescription)null); ConfigEntry<string> keyEntry6 = config.Bind<string>("Keybinds.PlayerMode", "cycle_target_left_key", "o", (ConfigDescription)null); ConfigEntry<string> keyEntry7 = config.Bind<string>("Keybinds.PlayerMode", "cycle_target_right_key", "p", (ConfigDescription)null); InputKeys.HOST_GHOST_MODE_KEY = GetKeyControlFromConfig(keyEntry5, InputKeys.HOST_GHOST_MODE_KEY); InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_LEFT = GetKeyControlFromConfig(keyEntry6, InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_LEFT); InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_RIGHT = GetKeyControlFromConfig(keyEntry7, InputKeys.HOST_CYCLE_PLAYER_TARGET_LIST_KEY_RIGHT); ConfigEntry<string> keyEntry8 = config.Bind<string>("Keybinds.PlayerMode", "extended_teleport_to_entrance_key", "9", (ConfigDescription)null); InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY = GetKeyControlFromConfig(keyEntry8, InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY); ConfigEntry<string> keyEntry9 = config.Bind<string>("Keybinds.GhostMode", "jump", "space", (ConfigDescription)null); InputKeys.CONTROLLER_JUMP_KEY = GetKeyControlFromConfig(keyEntry9, InputKeys.CONTROLLER_JUMP_KEY); ConfigEntry<string> keyEntry10 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_1", "f1", (ConfigDescription)null); ConfigEntry<string> keyEntry11 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_2", "f2", (ConfigDescription)null); ConfigEntry<string> keyEntry12 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_3", "f3", (ConfigDescription)null); ConfigEntry<string> keyEntry13 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_4", "f4", (ConfigDescription)null); ConfigEntry<string> keyEntry14 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_5", "f5", (ConfigDescription)null); ConfigEntry<string> keyEntry15 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_6", "f6", (ConfigDescription)null); ConfigEntry<string> keyEntry16 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_7", "f7", (ConfigDescription)null); ConfigEntry<string> keyEntry17 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_8", "f8", (ConfigDescription)null); ConfigEntry<string> keyEntry18 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_9", "f9", (ConfigDescription)null); ConfigEntry<string> keyEntry19 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_10", "f10", (ConfigDescription)null); ConfigEntry<string> keyEntry20 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_11", "f11", (ConfigDescription)null); ConfigEntry<string> keyEntry21 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_12", "f12", (ConfigDescription)null); InputKeys.GHOST_SPAWN_ENEMY_1 = GetKeyControlFromConfig(keyEntry10, InputKeys.GHOST_SPAWN_ENEMY_1); InputKeys.GHOST_SPAWN_ENEMY_2 = GetKeyControlFromConfig(keyEntry11, InputKeys.GHOST_SPAWN_ENEMY_2); InputKeys.GHOST_SPAWN_ENEMY_3 = GetKeyControlFromConfig(keyEntry12, InputKeys.GHOST_SPAWN_ENEMY_3); InputKeys.GHOST_SPAWN_ENEMY_4 = GetKeyControlFromConfig(keyEntry13, InputKeys.GHOST_SPAWN_ENEMY_4); InputKeys.GHOST_SPAWN_ENEMY_5 = GetKeyControlFromConfig(keyEntry14, InputKeys.GHOST_SPAWN_ENEMY_5); InputKeys.GHOST_SPAWN_ENEMY_6 = GetKeyControlFromConfig(keyEntry15, InputKeys.GHOST_SPAWN_ENEMY_6); InputKeys.GHOST_SPAWN_ENEMY_7 = GetKeyControlFromConfig(keyEntry16, InputKeys.GHOST_SPAWN_ENEMY_7); InputKeys.GHOST_SPAWN_ENEMY_8 = GetKeyControlFromConfig(keyEntry17, InputKeys.GHOST_SPAWN_ENEMY_8); InputKeys.GHOST_SPAWN_ENEMY_9 = GetKeyControlFromConfig(keyEntry18, InputKeys.GHOST_SPAWN_ENEMY_9); InputKeys.GHOST_SPAWN_ENEMY_10 = GetKeyControlFromConfig(keyEntry19, InputKeys.GHOST_SPAWN_ENEMY_10); InputKeys.GHOST_SPAWN_ENEMY_11 = GetKeyControlFromConfig(keyEntry20, InputKeys.GHOST_SPAWN_ENEMY_11); InputKeys.GHOST_SPAWN_ENEMY_12 = GetKeyControlFromConfig(keyEntry21, InputKeys.GHOST_SPAWN_ENEMY_12); InputKeys.GHOST_SPAWN_ENEMY_KEYS = new List<KeyControl> { InputKeys.GHOST_SPAWN_ENEMY_1, InputKeys.GHOST_SPAWN_ENEMY_2, InputKeys.GHOST_SPAWN_ENEMY_3, InputKeys.GHOST_SPAWN_ENEMY_4, InputKeys.GHOST_SPAWN_ENEMY_5, InputKeys.GHOST_SPAWN_ENEMY_6, InputKeys.GHOST_SPAWN_ENEMY_7, InputKeys.GHOST_SPAWN_ENEMY_8, InputKeys.GHOST_SPAWN_ENEMY_9, InputKeys.GHOST_SPAWN_ENEMY_10, InputKeys.GHOST_SPAWN_ENEMY_11, InputKeys.GHOST_SPAWN_ENEMY_12 }; ConfigEntry<string> keyEntry22 = config.Bind<string>("Keybinds.MonsterMode", "toggle_ai_key", "f1", (ConfigDescription)null); InputKeys.ENEMY_TOGGLE_AI_KEY = GetKeyControlFromConfig(keyEntry22, InputKeys.ENEMY_TOGGLE_AI_KEY); } private KeyControl GetKeyControlFromConfig(ConfigEntry<string> keyEntry, KeyControl defaultKey) { try { KeyControl val = Keyboard.current.FindKeyOnCurrentKeyboardLayout(keyEntry.Value); if (val != null) { return val; } return defaultKey; } catch (Exception ex) { ControlCompanyPlugin.Instance.logger.LogError((object)("Cannot rebind key for " + ((ConfigEntryBase)keyEntry).Definition.Key + " to " + keyEntry.Value + ": " + ex.Message)); return defaultKey; } } } public class EnemyAttributes { public float WalkSpeed { get; set; } = 5f; public float RunSpeed { get; set; } = 7f; public bool PlayerControlsRotation { get; set; } = true; public float CamHeight { get; set; } = 2f; public float CamDistance { get; set; } = -3.5f; public string EnemyName { get; set; } = ""; } internal static class EnemyConfiguration { public static HashSet<Type> ALLOWLISTED_ENEMIES = new HashSet<Type> { typeof(BlobAI), typeof(NutcrackerEnemyAI), typeof(HoarderBugAI), typeof(CrawlerAI), typeof(PufferAI), typeof(CentipedeAI), typeof(JesterAI), typeof(ForestGiantAI), typeof(BaboonBirdAI), typeof(FlowermanAI) }; public static HashSet<Type> EXPERIMENTAL_ENEMIES = new HashSet<Type> { typeof(MouthDogAI) }; public const float DEFAULT_WALK_SPEED = 5f; public const float DEFAULT_RUN_SPEED = 7f; public const float DEFAULT_CAM_DISTANCE = -3.5f; public const float DEFAULT_CAM_HEIGHT = 2f; public const bool DEFAULT_PLAYER_CONTROLS_ROTATION = true; public static Dictionary<Type, EnemyAttributes> ENEMY_ATTRIBUTES = new Dictionary<Type, EnemyAttributes> { { typeof(BlobAI), new EnemyAttributes { WalkSpeed = 2f, RunSpeed = 2f, PlayerControlsRotation = false, EnemyName = "Blob" } }, { typeof(CrawlerAI), new EnemyAttributes { WalkSpeed = 6f, RunSpeed = 12f, EnemyName = "Thumper" } }, { typeof(JesterAI), new EnemyAttributes { WalkSpeed = 4f, RunSpeed = 6f, EnemyName = "Jester" } }, { typeof(ForestGiantAI), new EnemyAttributes { WalkSpeed = 5f, RunSpeed = 7f, CamDistance = -7f, CamHeight = 10f, EnemyName = "Forest Keeper" } }, { typeof(MouthDogAI), new EnemyAttributes { WalkSpeed = 4f, RunSpeed = 8f, CamDistance = -5f, CamHeight = 5f, EnemyName = "Eyeless Dog" } }, { typeof(FlowermanAI), new EnemyAttributes { EnemyName = "Bracken", RunSpeed = 8f } }, { typeof(PufferAI), new EnemyAttributes { EnemyName = "Spore Lizard" } }, { typeof(HoarderBugAI), new EnemyAttributes { EnemyName = "Hoarding Bug" } }, { typeof(CentipedeAI), new EnemyAttributes { EnemyName = "Snare Flea", CamHeight = 1.5f, CamDistance = -3f } }, { typeof(SpringManAI), new EnemyAttributes { EnemyName = "Coil-Head" } }, { typeof(SandSpiderAI), new EnemyAttributes { EnemyName = "Bunker Spider" } }, { typeof(DressGirlAI), new EnemyAttributes { EnemyName = "Ghost Girl" } }, { typeof(MaskedPlayerEnemy), new EnemyAttributes { EnemyName = "Masked" } } }; private static readonly EnemyAttributes DEFAULT_ATTRIBUTES = new EnemyAttributes(); public static Dictionary<Type, Func<GameObject, EnemyController>> ENEMY_CONTROLLERS = new Dictionary<Type, Func<GameObject, EnemyController>> { { typeof(NutcrackerEnemyAI), (GameObject controller) => controller.AddComponent<NutcrackerEnemyController>() }, { typeof(CentipedeAI), (GameObject controller) => controller.AddComponent<CentipedeEnemyController>() }, { typeof(PufferAI), (GameObject controller) => controller.AddComponent<PufferEnemyController>() }, { typeof(JesterAI), (GameObject controller) => controller.AddComponent<JesterEnemyController>() }, { typeof(ForestGiantAI), (GameObject controller) => controller.AddComponent<ForestGiantEnemyController>() }, { typeof(MouthDogAI), (GameObject controller) => controller.AddComponent<MouthDogEnemyController>() }, { typeof(HoarderBugAI), (GameObject controller) => controller.AddComponent<HoardingBugEnemyController>() }, { typeof(FlowermanAI), (GameObject controller) => controller.AddComponent<FlowermanEnemyController>() } }; public static EnemyAttributes GetEnemyAttributes(this EnemyAI enemyAI) { return ExtensionMethods.GetValueOrDefault(ENEMY_ATTRIBUTES, ((object)enemyAI).GetType(), DEFAULT_ATTRIBUTES); } public static bool IsEnemyAllowlisted(this EnemyAI enemyAI) { return ALLOWLISTED_ENEMIES.Contains(((object)enemyAI).GetType()); } public static bool IsEnemyExperimental(this EnemyAI enemyAI) { return EXPERIMENTAL_ENEMIES.Contains(((object)enemyAI).GetType()); } public static string GetEnemyName(this EnemyAI enemyAI) { EnemyAttributes valueOrDefault = ExtensionMethods.GetValueOrDefault(ENEMY_ATTRIBUTES, ((object)enemyAI).GetType(), null); if (valueOrDefault == null) { return enemyAI.enemyType.enemyName; } return valueOrDefault.EnemyName; } public static EnemyController GetAndAttachEnemyController(this EnemyAI enemyAI, GameObject controller) { return ExtensionMethods.GetValueOrDefault(ENEMY_CONTROLLERS, ((object)enemyAI).GetType(), (GameObject c) => c.AddComponent<EnemyController>())(controller); } } }