using 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);
}
}
}