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 Sector v1.2.0
Sector.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Empress")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("Sector")] [assembly: AssemblyTitle("Sector")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Empress.Sector { internal static class SectorAccess { private static readonly FieldInfo? PlayerAvatarPlayerHealthField = AccessTools.Field(typeof(PlayerAvatar), "playerHealth"); private static readonly FieldInfo? PlayerAvatarPlayerDeathHeadField = AccessTools.Field(typeof(PlayerAvatar), "playerDeathHead"); private static readonly FieldInfo? PlayerAvatarPlayerNameField = AccessTools.Field(typeof(PlayerAvatar), "playerName"); private static readonly FieldInfo? PlayerAvatarIsLocalField = AccessTools.Field(typeof(PlayerAvatar), "isLocal"); private static readonly FieldInfo? PlayerAvatarIsDisabledField = AccessTools.Field(typeof(PlayerAvatar), "isDisabled"); private static readonly FieldInfo? PlayerAvatarDeadSetField = AccessTools.Field(typeof(PlayerAvatar), "deadSet"); private static readonly FieldInfo? PlayerHealthHealthField = AccessTools.Field(typeof(PlayerHealth), "health"); private static readonly FieldInfo? PlayerHealthMaxHealthField = AccessTools.Field(typeof(PlayerHealth), "maxHealth"); private static readonly FieldInfo? PlayerHealthGodModeField = AccessTools.Field(typeof(PlayerHealth), "godMode"); private static readonly FieldInfo? PlayerControllerDebugEnergyField = AccessTools.Field(typeof(PlayerController), "DebugEnergy"); private static readonly FieldInfo? PlayerControllerEnergyCurrentField = AccessTools.Field(typeof(PlayerController), "EnergyCurrent"); private static readonly FieldInfo? PlayerControllerEnergyStartField = AccessTools.Field(typeof(PlayerController), "EnergyStart"); private static readonly FieldInfo? PlayerControllerAvatarField = AccessTools.Field(typeof(PlayerController), "playerAvatarScript"); private static readonly FieldInfo? PlayerDeathHeadInExtractionPointField = AccessTools.Field(typeof(PlayerDeathHead), "inExtractionPoint"); private static readonly FieldInfo? EnemyDirectorDebugNoVisionField = AccessTools.Field(typeof(EnemyDirector), "debugNoVision"); private static readonly FieldInfo? EnemyDirectorDebugNoSpawnIdlePauseField = AccessTools.Field(typeof(EnemyDirector), "debugNoSpawnIdlePause"); private static readonly FieldInfo? EnemyDirectorDebugSpawnCloseField = AccessTools.Field(typeof(EnemyDirector), "debugSpawnClose"); private static readonly FieldInfo? EnemyDirectorEnemiesSpawnedField = AccessTools.Field(typeof(EnemyDirector), "enemiesSpawned"); private static readonly FieldInfo? EnemyParentSpawnedField = AccessTools.Field(typeof(EnemyParent), "Spawned"); private static readonly FieldInfo? EnemyParentSetupDoneField = AccessTools.Field(typeof(EnemyParent), "SetupDone"); private static readonly FieldInfo? EnemyParentFirstSpawnPointUsedField = AccessTools.Field(typeof(EnemyParent), "firstSpawnPointUsed"); private static readonly FieldInfo? ValuableObjectPhysGrabObjectField = AccessTools.Field(typeof(ValuableObject), "physGrabObject"); private static readonly FieldInfo? RoundDirectorExtractionPointCurrentField = AccessTools.Field(typeof(RoundDirector), "extractionPointCurrent"); private static readonly FieldInfo? ExtractionPointCurrentStateField = AccessTools.Field(typeof(ExtractionPoint), "currentState"); private static readonly FieldInfo? RunManagerDebugLevelField = AccessTools.Field(typeof(RunManager), "debugLevel"); private static readonly FieldInfo? RunManagerGameOverField = AccessTools.Field(typeof(RunManager), "gameOver"); private static readonly FieldInfo? MenuCursorMeshField = AccessTools.Field(typeof(MenuCursor), "mesh"); private static readonly FieldInfo? MenuCursorShowTimerField = AccessTools.Field(typeof(MenuCursor), "showTimer"); private static readonly FieldInfo? MenuCursorOverridePosTimerField = AccessTools.Field(typeof(MenuCursor), "overridePosTimer"); private static readonly FieldInfo? CursorManagerUnlockTimerField = AccessTools.Field(typeof(CursorManager), "unlockTimer"); public static PlayerHealth? GetPlayerHealth(PlayerAvatar? player) { return GetFieldValue<PlayerHealth>(PlayerAvatarPlayerHealthField, player); } public static PlayerDeathHead? GetPlayerDeathHead(PlayerAvatar? player) { return GetFieldValue<PlayerDeathHead>(PlayerAvatarPlayerDeathHeadField, player); } public static string GetPlayerName(PlayerAvatar? player) { return GetFieldValue(PlayerAvatarPlayerNameField, player, "Unknown operative"); } public static bool IsPlayerLocal(PlayerAvatar? player) { return GetFieldValue(PlayerAvatarIsLocalField, player, fallback: false); } public static bool IsPlayerDisabled(PlayerAvatar? player) { return GetFieldValue(PlayerAvatarIsDisabledField, player, fallback: false); } public static bool IsPlayerDead(PlayerAvatar? player) { return GetFieldValue(PlayerAvatarDeadSetField, player, fallback: false); } public static int GetHealth(PlayerHealth? playerHealth) { return GetFieldValue(PlayerHealthHealthField, playerHealth, 0); } public static int GetMaxHealth(PlayerHealth? playerHealth) { return GetFieldValue(PlayerHealthMaxHealthField, playerHealth, 0); } public static void SetPlayerGodMode(PlayerHealth? playerHealth, bool enabled) { SetFieldValue(PlayerHealthGodModeField, playerHealth, enabled); } public static float GetEnergyCurrent(PlayerController? playerController) { return GetFieldValue(PlayerControllerEnergyCurrentField, playerController, 0f); } public static float GetEnergyStart(PlayerController? playerController) { return GetFieldValue(PlayerControllerEnergyStartField, playerController, 0f); } public static void SetEnergyCurrent(PlayerController? playerController, float value) { SetFieldValue(PlayerControllerEnergyCurrentField, playerController, value); } public static void SetDebugEnergy(PlayerController? playerController, bool enabled) { SetFieldValue(PlayerControllerDebugEnergyField, playerController, enabled); } public static PlayerAvatar? GetControllerAvatar(PlayerController? playerController) { return GetFieldValue<PlayerAvatar>(PlayerControllerAvatarField, playerController); } public static void SetInExtractionPoint(PlayerDeathHead? playerDeathHead, bool enabled) { SetFieldValue(PlayerDeathHeadInExtractionPointField, playerDeathHead, enabled); } public static bool GetEnemyNoVision(EnemyDirector? enemyDirector) { return GetFieldValue(EnemyDirectorDebugNoVisionField, enemyDirector, fallback: false); } public static void SetEnemyNoVision(EnemyDirector? enemyDirector, bool enabled) { SetFieldValue(EnemyDirectorDebugNoVisionField, enemyDirector, enabled); } public static bool GetEnemyNoSpawnIdlePause(EnemyDirector? enemyDirector) { return GetFieldValue(EnemyDirectorDebugNoSpawnIdlePauseField, enemyDirector, fallback: false); } public static void SetEnemyNoSpawnIdlePause(EnemyDirector? enemyDirector, bool enabled) { SetFieldValue(EnemyDirectorDebugNoSpawnIdlePauseField, enemyDirector, enabled); } public static bool GetEnemySpawnClose(EnemyDirector? enemyDirector) { return GetFieldValue(EnemyDirectorDebugSpawnCloseField, enemyDirector, fallback: false); } public static void SetEnemySpawnClose(EnemyDirector? enemyDirector, bool enabled) { SetFieldValue(EnemyDirectorDebugSpawnCloseField, enemyDirector, enabled); } public static List<EnemyParent> GetSpawnedEnemies(EnemyDirector? enemyDirector) { return GetFieldValue(EnemyDirectorEnemiesSpawnedField, enemyDirector, new List<EnemyParent>()); } public static bool IsEnemySpawned(EnemyParent? enemyParent) { return GetFieldValue(EnemyParentSpawnedField, enemyParent, fallback: false); } public static void SetEnemySetupDone(EnemyParent? enemyParent, bool enabled) { SetFieldValue(EnemyParentSetupDoneField, enemyParent, enabled); } public static void SetEnemyFirstSpawnPointUsed(EnemyParent? enemyParent, bool enabled) { SetFieldValue(EnemyParentFirstSpawnPointUsedField, enemyParent, enabled); } public static GameObject? GetMenuCursorMesh(MenuCursor? menuCursor) { return GetFieldValue<GameObject>(MenuCursorMeshField, menuCursor); } public static void SetMenuCursorShowTimer(MenuCursor? menuCursor, float value) { SetFieldValue(MenuCursorShowTimerField, menuCursor, value); } public static void SetMenuCursorOverridePosTimer(MenuCursor? menuCursor, float value) { SetFieldValue(MenuCursorOverridePosTimerField, menuCursor, value); } public static void SetCursorUnlockTimer(CursorManager? cursorManager, float value) { SetFieldValue(CursorManagerUnlockTimerField, cursorManager, value); } public static PhysGrabObject? GetValuablePhysGrabObject(ValuableObject? valuableObject) { return GetFieldValue<PhysGrabObject>(ValuableObjectPhysGrabObjectField, valuableObject); } public static ExtractionPoint? GetRoundExtractionPointCurrent(RoundDirector? roundDirector) { return GetFieldValue<ExtractionPoint>(RoundDirectorExtractionPointCurrentField, roundDirector); } public static State GetExtractionPointState(ExtractionPoint? extractionPoint) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return GetFieldValue<State>(ExtractionPointCurrentStateField, extractionPoint, (State)0); } public static bool GetRunGameOver(RunManager? runManager) { return GetFieldValue(RunManagerGameOverField, runManager, fallback: false); } public static void SetRunDebugLevel(RunManager? runManager, Level? level) { SetFieldValue<Level>(RunManagerDebugLevelField, runManager, level); } private static T GetFieldValue<T>(FieldInfo? fieldInfo, object? instance, T fallback = default(T)) { if (fieldInfo == null || instance == null) { return fallback; } try { return (T)((fieldInfo.GetValue(instance) is T val) ? ((object)val) : ((object)fallback)); } catch { return fallback; } } private static void SetFieldValue<T>(FieldInfo? fieldInfo, object? instance, T value) { if (fieldInfo == null || instance == null) { return; } try { fieldInfo.SetValue(instance, value); } catch { } } } internal sealed class SectorActions { private const float InfiniteStrengthGrabValue = 100f; private readonly ManualLogSource _logger; private readonly SectorOverlayState _state; private readonly SectorCatalog _catalog; private PhysGrabber? _strengthGrabber; private float _strengthGrabberOriginal = 1f; public SectorActions(ManualLogSource logger, SectorOverlayState state, SectorCatalog catalog) { _logger = logger; _state = state; _catalog = catalog; } public void Tick() { try { ApplyLocalPowerState(); } catch (Exception ex) { _logger.LogError((object)ex); } } public void ResetLocalPowerState() { PlayerHealth playerHealth = SectorAccess.GetPlayerHealth(PlayerAvatar.instance); if ((Object)(object)playerHealth != (Object)null) { SectorAccess.SetPlayerGodMode(playerHealth, enabled: false); } if ((Object)(object)PlayerController.instance != (Object)null) { SectorAccess.SetDebugEnergy(PlayerController.instance, enabled: false); PlayerController.instance.OverrideSpeed(1f, 0.05f); } _state.GodMode = false; _state.InfiniteEnergy = false; RestoreInfiniteStrength(); _state.InfiniteStrength = false; _state.StickyBoost = false; } public SectorRuntimeSnapshot GetSnapshot() { List<PlayerAvatar> list = SectorGame.GetPlayers().ToList(); PlayerHealth playerHealth = SectorAccess.GetPlayerHealth(SectorGame.GetLocalPlayer()); PlayerController instance = PlayerController.instance; List<EnemyParent> spawnedEnemies = SectorAccess.GetSpawnedEnemies(EnemyDirector.instance); bool inRun = SectorGame.IsInPlayableRun(); bool isHost = SemiFunc.IsMasterClientOrSingleplayer(); object obj = RunManager.instance?.levelCurrent?.NarrativeName; if (obj == null) { RunManager instance2 = RunManager.instance; if (instance2 == null) { obj = null; } else { Level levelCurrent = instance2.levelCurrent; obj = ((levelCurrent != null) ? ((Object)levelCurrent).name : null); } if (obj == null) { obj = "No active level"; } } return new SectorRuntimeSnapshot(inRun, isHost, (string)obj, list.Count, list.Count((PlayerAvatar player) => (Object)(object)player != (Object)null && !SectorAccess.IsPlayerDead(player) && !SectorAccess.IsPlayerDisabled(player)), list.Count((PlayerAvatar player) => (Object)(object)player != (Object)null && SectorAccess.IsPlayerDead(player)), spawnedEnemies.Count((EnemyParent enemy) => (Object)(object)enemy != (Object)null), Object.FindObjectsByType<ValuableObject>((FindObjectsSortMode)0).Length, SectorAccess.GetHealth(playerHealth), SectorAccess.GetMaxHealth(playerHealth), SectorAccess.GetEnergyCurrent(instance), SectorAccess.GetEnergyStart(instance), SectorAccess.GetEnemyNoVision(EnemyDirector.instance)); } public void ExecuteCommand(string input) { string text = (input ?? string.Empty).Trim(); if (string.IsNullOrEmpty(text)) { _state.PushToast("Command deck is empty."); return; } string[] array = text.Split(' ', StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { _state.PushToast("Command deck is empty."); return; } switch (array[0].ToLowerInvariant()) { case "help": _state.PushToast("Commands: spawn, heal, revive, despawn, destroy, noaggro, energy, god, strength, boost, truck, level."); return; case "spawn": ExecuteSpawnCommand(array); return; case "heal": ExecuteHealCommand(array); return; case "revive": ExecuteReviveCommand(array); return; case "despawn": if (array.Length >= 2 && array[1].Equals("enemies", StringComparison.OrdinalIgnoreCase)) { DespawnEnemies(); return; } break; case "destroy": if (array.Length >= 2 && array[1].Equals("enemies", StringComparison.OrdinalIgnoreCase)) { DestroyEnemies(); return; } break; case "noaggro": SetNoAggro(array.Length < 2 || ParseToggle(array[1], _state.NoAggro)); return; case "energy": SetInfiniteEnergy(array.Length < 2 || ParseToggle(array[1], _state.InfiniteEnergy)); return; case "god": SetGodMode(array.Length < 2 || ParseToggle(array[1], _state.GodMode)); return; case "strength": SetInfiniteStrength(array.Length < 2 || ParseToggle(array[1], _state.InfiniteStrength)); return; case "boost": ExecuteBoostCommand(array); return; case "truck": if (array.Length >= 2 && array[1].Equals("valuables", StringComparison.OrdinalIgnoreCase)) { RecallValuablesToTruck(); return; } break; case "level": ExecuteLevelCommand(array); return; } _state.PushToast("Unknown command: " + text); } public void Spawn(SectorSpawnEntry entry, int count) { count = Mathf.Clamp(count, 1, 25); if (EnsureHostTools("spawning")) { switch (entry.Kind) { case SectorSpawnKind.Enemy: SpawnEnemyEntry(entry, count); break; case SectorSpawnKind.Item: SpawnItemEntry(entry, count); break; case SectorSpawnKind.Valuable: SpawnValuableEntry(entry, count); break; } } } public void RefillLocalPlayer() { PlayerHealth playerHealth = SectorAccess.GetPlayerHealth(PlayerAvatar.instance); if ((Object)(object)playerHealth != (Object)null) { int num = Mathf.Max(0, SectorAccess.GetMaxHealth(playerHealth) - SectorAccess.GetHealth(playerHealth)); if (num > 0) { playerHealth.Heal(num, true); } } if ((Object)(object)PlayerController.instance != (Object)null) { SectorAccess.SetEnergyCurrent(PlayerController.instance, SectorAccess.GetEnergyStart(PlayerController.instance)); } _state.PushToast("Local player refilled."); } public void HealPlayer(PlayerAvatar? player) { PlayerHealth playerHealth = SectorAccess.GetPlayerHealth(player); if ((Object)(object)playerHealth == (Object)null) { _state.PushToast("Player health is unavailable."); return; } int num = Mathf.Max(0, SectorAccess.GetMaxHealth(playerHealth) - SectorAccess.GetHealth(playerHealth)); if (num <= 0) { _state.PushToast(SectorAccess.GetPlayerName(player) + " is already full."); return; } playerHealth.HealOther(num, true); _state.PushToast("Healed " + SectorAccess.GetPlayerName(player) + "."); } public void HealAllPlayers() { int num = 0; foreach (PlayerAvatar player in SectorGame.GetPlayers()) { PlayerHealth playerHealth = SectorAccess.GetPlayerHealth(player); if (!((Object)(object)playerHealth == (Object)null)) { int num2 = Mathf.Max(0, SectorAccess.GetMaxHealth(playerHealth) - SectorAccess.GetHealth(playerHealth)); if (num2 > 0) { playerHealth.HealOther(num2, true); num++; } } } _state.PushToast((num > 0) ? $"Healed {num} player(s)." : "Nobody needed healing."); } public void RevivePlayer(PlayerAvatar? player) { PlayerDeathHead playerDeathHead = SectorAccess.GetPlayerDeathHead(player); if ((Object)(object)player == (Object)null || !SectorAccess.IsPlayerDead(player) || (Object)(object)playerDeathHead == (Object)null) { _state.PushToast("That player is not in a revivable state."); } else if (EnsureHostTools("reviving")) { SectorAccess.SetInExtractionPoint(playerDeathHead, enabled: true); playerDeathHead.Revive(); _state.PushToast("Revive requested for " + SectorAccess.GetPlayerName(player) + "."); } } public void ReviveAllPlayers() { if (!EnsureHostTools("reviving")) { return; } int num = 0; foreach (PlayerAvatar player in SectorGame.GetPlayers()) { PlayerDeathHead playerDeathHead = SectorAccess.GetPlayerDeathHead(player); if (!((Object)(object)player == (Object)null) && SectorAccess.IsPlayerDead(player) && !((Object)(object)playerDeathHead == (Object)null)) { SectorAccess.SetInExtractionPoint(playerDeathHead, enabled: true); playerDeathHead.Revive(); num++; } } _state.PushToast((num > 0) ? $"Revive requested for {num} player(s)." : "No dead players found."); } public void DespawnEnemies() { if (!EnsureHostTools("enemy despawn")) { return; } int num = 0; if ((Object)(object)EnemyDirector.instance != (Object)null) { foreach (EnemyParent item in SectorAccess.GetSpawnedEnemies(EnemyDirector.instance).ToList()) { if (!((Object)(object)item == (Object)null) && SectorAccess.IsEnemySpawned(item)) { item.SpawnedTimerSet(0f); item.DespawnedTimerSet(10f, false); num++; } } } _state.PushToast((num > 0) ? $"Queued {num} enemy despawn(s)." : "No spawned enemies to despawn."); } public void DestroyEnemies() { if (!EnsureHostTools("enemy destroy")) { return; } int num = 0; if ((Object)(object)EnemyDirector.instance != (Object)null) { List<EnemyParent> spawnedEnemies = SectorAccess.GetSpawnedEnemies(EnemyDirector.instance); foreach (EnemyParent item in spawnedEnemies.ToList()) { if (!((Object)(object)item == (Object)null)) { spawnedEnemies.Remove(item); if (SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(((Component)item).gameObject); } else { Object.Destroy((Object)(object)((Component)item).gameObject); } num++; } } } _state.PushToast((num > 0) ? $"Destroyed {num} enemy object(s)." : "No enemies found."); } public void RecallValuablesToTruck() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (!EnsureHostTools("valuable recall")) { return; } if ((Object)(object)TruckSafetySpawnPoint.instance == (Object)null) { _state.PushToast("Truck safety spawn is unavailable in this scene."); return; } ValuableObject[] array = Object.FindObjectsByType<ValuableObject>((FindObjectsSortMode)0); int num = 0; Vector3 val2 = default(Vector3); for (int i = 0; i < array.Length; i++) { ValuableObject val = array[i]; PhysGrabObject valuablePhysGrabObject = SectorAccess.GetValuablePhysGrabObject(val); if (!((Object)(object)valuablePhysGrabObject == (Object)null)) { int num2 = i % 8; int num3 = i / 8; float num4 = (float)num2 / 8f * MathF.PI * 2f; float num5 = 1.2f + (float)num3 * 0.8f; ((Vector3)(ref val2))..ctor(Mathf.Cos(num4) * num5, 0.35f + (float)num3 * 0.1f, Mathf.Sin(num4) * num5); valuablePhysGrabObject.Teleport(((Component)TruckSafetySpawnPoint.instance).transform.position + val2, ((Component)TruckSafetySpawnPoint.instance).transform.rotation); val.DollarValueSetLogic(); num++; } } _state.PushToast((num > 0) ? $"Recalled {num} valuable(s) to the truck." : "No valuables found."); } public void ForceEnemyInvestigateHere() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (EnsureHostTools("enemy redirect")) { PlayerAvatar localPlayer = SectorGame.GetLocalPlayer(); if ((Object)(object)localPlayer == (Object)null) { _state.PushToast("Local player anchor is unavailable."); return; } SemiFunc.EnemyInvestigate(((Component)localPlayer).transform.position, 100f, true); _state.PushToast("Enemies redirected toward your position."); } } public void ToggleSpawnIdlePause() { if (EnsureHostTools("enemy idle timer toggle")) { if ((Object)(object)EnemyDirector.instance == (Object)null) { _state.PushToast("Enemy director is unavailable."); return; } bool flag = !SectorAccess.GetEnemyNoSpawnIdlePause(EnemyDirector.instance); SectorAccess.SetEnemyNoSpawnIdlePause(EnemyDirector.instance, flag); _state.PushToast(flag ? "Enemy spawn idle pause disabled." : "Enemy spawn idle pause restored."); } } public void SwitchLevel(string target) { string text = (target ?? string.Empty).Trim(); if (string.IsNullOrEmpty(text)) { _state.PushToast("Type a level target or use one of the quick switch buttons."); } else { if (!EnsureHostTools("level switching")) { return; } if ((Object)(object)RunManager.instance == (Object)null) { _state.PushToast("Run manager is unavailable."); return; } switch (text.ToLowerInvariant()) { case "next": RunManager.instance.ChangeLevel(true, SemiFunc.RunIsArena(), (ChangeLevelType)0); _state.PushToast("Advancing to the next level."); break; case "random": RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)1); _state.PushToast("Switching to a random run level."); break; case "refresh": RunManager.instance.RestartScene(); if (!SemiFunc.RunIsTutorial()) { SemiFunc.OnSceneSwitch(SectorAccess.GetRunGameOver(RunManager.instance), false); } _state.PushToast("Refreshing the current level."); break; case "shop": RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)5); _state.PushToast("Switching to the shop."); break; case "recording": RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)6); _state.PushToast("Switching to the recording level."); break; case "lobby": SwitchToSpecificLevel(RunManager.instance.levelLobby); break; case "arena": SwitchToSpecificLevel(RunManager.instance.levelArena); break; default: { Level val = FindLevelMatch(text); if ((Object)(object)val == (Object)null) { _state.PushToast("No level matched '" + text + "'."); } else { SwitchToSpecificLevel(val); } break; } } } } public void AddMoney(int amount) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Invalid comparison between Unknown and I4 if (amount <= 0) { _state.PushToast("Money amount must be above zero."); } else { if (!EnsureCurrencyTools()) { return; } int num = SemiFunc.StatGetRunCurrency(); int num2 = ((num > int.MaxValue - amount) ? int.MaxValue : (num + amount)); SemiFunc.StatSetRunCurrency(num2); CurrencyUI instance = CurrencyUI.instance; if (instance != null) { instance.FetchCurrency(); } if (SemiFunc.RunIsShop()) { RunManager instance2 = RunManager.instance; if (instance2 != null) { instance2.ChangeLevel(false, false, (ChangeLevelType)5); } } else if (SemiFunc.RunIsLevel() && (int)SectorAccess.GetExtractionPointState(SectorAccess.GetRoundExtractionPointCurrent(RoundDirector.instance)) > 1) { RunManager instance3 = RunManager.instance; if (instance3 != null) { instance3.ChangeLevel(false, false, (ChangeLevelType)0); } } _state.PushToast("Added " + SemiFunc.DollarGetString(amount) + ". Cash now " + SemiFunc.DollarGetString(num2) + "."); } } public void AddMoney(string amountText) { if (!int.TryParse((amountText ?? string.Empty).Trim(), out var result)) { _state.PushToast("Enter a whole number for cash."); } else { AddMoney(result); } } public IReadOnlyList<string> GetLevelSuggestions(string search) { if (RunManager.instance?.levels == null) { return Array.Empty<string>(); } IEnumerable<Level> source = RunManager.instance.levels.Where((Level level) => (Object)(object)level != (Object)null); string trimmedSearch = (search ?? string.Empty).Trim(); if (!string.IsNullOrEmpty(trimmedSearch)) { source = source.Where((Level level) => LevelMatches(level, trimmedSearch, allowPartial: true)); } return (from name in (from name in source.Select(GetLevelDisplayName) where !string.IsNullOrWhiteSpace(name) select name).Distinct<string>(StringComparer.OrdinalIgnoreCase) orderby name select name).Take(8).ToList(); } public void SetGodMode(bool enabled) { _state.GodMode = enabled; _state.PushToast(enabled ? "God mode armed for the local player." : "God mode disabled."); } public void SetInfiniteEnergy(bool enabled) { _state.InfiniteEnergy = enabled; _state.PushToast(enabled ? "Infinite energy armed." : "Infinite energy disabled."); } public void SetInfiniteStrength(bool enabled) { _state.InfiniteStrength = enabled; if (!enabled) { RestoreInfiniteStrength(); } _state.PushToast(enabled ? "Infinite strength armed. Pick up whatever you want." : "Infinite strength disabled."); } public void SetNoAggro(bool enabled) { _state.NoAggro = enabled; if ((Object)(object)EnemyDirector.instance != (Object)null) { SectorAccess.SetEnemyNoVision(EnemyDirector.instance, enabled); } _state.PushToast(enabled ? "Enemy vision disabled." : "Enemy vision restored."); } private void ApplyLocalPowerState() { PlayerAvatar localPlayer = SectorGame.GetLocalPlayer(); PlayerHealth playerHealth = SectorAccess.GetPlayerHealth(localPlayer); if ((Object)(object)playerHealth != (Object)null) { SectorAccess.SetPlayerGodMode(playerHealth, _state.GodMode); } if ((Object)(object)PlayerController.instance != (Object)null) { SectorAccess.SetDebugEnergy(PlayerController.instance, _state.InfiniteEnergy); if (_state.InfiniteEnergy) { SectorAccess.SetEnergyCurrent(PlayerController.instance, SectorAccess.GetEnergyStart(PlayerController.instance)); } ApplyInfiniteStrength(localPlayer); if (_state.StickyBoost && _state.SpeedMultiplier > 1.01f) { PlayerController.instance.OverrideSpeed(_state.SpeedMultiplier, 0.25f); } } if ((Object)(object)EnemyDirector.instance != (Object)null) { SectorAccess.SetEnemyNoVision(EnemyDirector.instance, _state.NoAggro); } } private void ApplyInfiniteStrength(PlayerAvatar? localPlayer) { PhysGrabber val = localPlayer?.physGrabber ?? PhysGrabber.instance; if (!_state.InfiniteStrength) { RestoreInfiniteStrength(); } else if (!((Object)(object)val == (Object)null)) { if ((Object)(object)_strengthGrabber != (Object)(object)val) { RestoreInfiniteStrength(); _strengthGrabber = val; _strengthGrabberOriginal = Mathf.Max(1f, val.grabStrength); } val.grabStrength = 100f; } } private void RestoreInfiniteStrength() { PhysGrabber strengthGrabber = _strengthGrabber; if ((Object)(object)strengthGrabber == (Object)null) { _strengthGrabber = null; _strengthGrabberOriginal = 1f; } else { strengthGrabber.grabStrength = Mathf.Max(1f, _strengthGrabberOriginal); _strengthGrabber = null; _strengthGrabberOriginal = 1f; } } private void ExecuteSpawnCommand(string[] tokens) { if (tokens.Length < 3) { _state.PushToast("Usage: spawn enemy|item|valuable <name> [count]"); return; } int result = 1; bool num = int.TryParse(tokens[^1], out result); result = Mathf.Clamp(result, 1, 25); string text = tokens[1].ToLowerInvariant(); int startIndex = 2; int num2 = (num ? (tokens.Length - 3) : (tokens.Length - 2)); if (num2 < 1) { _state.PushToast("Spawn command is missing a target name."); return; } string text2 = string.Join(" ", tokens, startIndex, num2); if (!TryParseKind(text, out var kind)) { _state.PushToast("Unknown spawn type: " + text); return; } SectorSpawnEntry sectorSpawnEntry = _catalog.FindBestMatch(kind, text2); if (sectorSpawnEntry == null) { _state.PushToast("No " + text + " matched '" + text2 + "'."); } else { Spawn(sectorSpawnEntry, result); } } private void ExecuteHealCommand(string[] tokens) { if (tokens.Length < 2) { _state.PushToast("Usage: heal me|all"); return; } string text = tokens[1].ToLowerInvariant(); if (!(text == "me")) { if (text == "all") { HealAllPlayers(); } else { _state.PushToast("Usage: heal me|all"); } } else { RefillLocalPlayer(); } } private void ExecuteReviveCommand(string[] tokens) { if (tokens.Length < 2) { _state.PushToast("Usage: revive all"); } else if (tokens[1].Equals("all", StringComparison.OrdinalIgnoreCase)) { ReviveAllPlayers(); } else { _state.PushToast("Usage: revive all"); } } private void ExecuteBoostCommand(string[] tokens) { float result; if (tokens.Length < 2) { _state.StickyBoost = !_state.StickyBoost; _state.PushToast(_state.StickyBoost ? $"Sticky boost enabled at {_state.SpeedMultiplier:0.0}x." : "Sticky boost disabled."); } else if (tokens[1].Equals("off", StringComparison.OrdinalIgnoreCase)) { _state.StickyBoost = false; _state.PushToast("Sticky boost disabled."); } else if (float.TryParse(tokens[1], out result)) { _state.SpeedMultiplier = Mathf.Clamp(result, 1f, 4f); _state.StickyBoost = _state.SpeedMultiplier > 1.01f; _state.PushToast(_state.StickyBoost ? $"Sticky boost set to {_state.SpeedMultiplier:0.0}x." : "Sticky boost disabled."); } else { _state.PushToast("Usage: boost <multiplier>|off"); } } private void ExecuteLevelCommand(string[] tokens) { if (tokens.Length < 2) { _state.PushToast("Usage: level <next|random|refresh|shop|lobby|arena|recording|name>"); } else { SwitchLevel(string.Join(" ", tokens.Skip(1))); } } private void SpawnEnemyEntry(SectorSpawnEntry entry, int count) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entry.EnemySetup == (Object)null || entry.EnemySetup.spawnObjects == null || entry.EnemySetup.spawnObjects.Count == 0) { _state.PushToast("Enemy profile '" + entry.DisplayName + "' has no spawn objects."); return; } List<LevelPoint> list = SectorGame.GetSpawnPoints(count).ToList(); if (list.Count == 0) { _state.PushToast("No usable level points are available yet."); return; } int num = 0; bool enemySpawnClose = SectorAccess.GetEnemySpawnClose(EnemyDirector.instance); if ((Object)(object)EnemyDirector.instance != (Object)null) { SectorAccess.SetEnemySpawnClose(EnemyDirector.instance, enabled: true); } try { for (int i = 0; i < count; i++) { Vector3 val = ((Component)list[Mathf.Min(i, list.Count - 1)]).transform.position + Vector3.up * 0.1f; foreach (PrefabRef spawnObject in entry.EnemySetup.spawnObjects) { if (spawnObject == null || !spawnObject.IsValid()) { continue; } GameObject val2 = (SemiFunc.IsMultiplayer() ? PhotonNetwork.InstantiateRoomObject(spawnObject.ResourcePath, val, Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(spawnObject.Prefab, val, Quaternion.identity)); if ((Object)(object)val2 == (Object)null) { continue; } EnemyParent component = val2.GetComponent<EnemyParent>(); if ((Object)(object)component != (Object)null) { SectorAccess.SetEnemySetupDone(component, enabled: true); SectorAccess.SetEnemyFirstSpawnPointUsed(component, enabled: true); Enemy componentInChildren = ((Component)component).GetComponentInChildren<Enemy>(); if (componentInChildren != null) { componentInChildren.EnemyTeleported(val); } } } num++; } } finally { if ((Object)(object)EnemyDirector.instance != (Object)null) { SectorAccess.SetEnemySpawnClose(EnemyDirector.instance, enemySpawnClose); } } _state.PushToast($"Spawned {num} '{entry.DisplayName}' pack(s)."); } private void SpawnItemEntry(SectorSpawnEntry entry, int count) { //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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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) if (entry.Item?.prefab == null || !entry.Item.prefab.IsValid()) { _state.PushToast("Item '" + entry.DisplayName + "' is missing a valid prefab reference."); return; } List<LevelPoint> list = SectorGame.GetSpawnPoints(count).ToList(); if (list.Count == 0) { _state.PushToast("No usable level points are available yet."); return; } int num = 0; for (int i = 0; i < count; i++) { LevelPoint obj = list[Mathf.Min(i, list.Count - 1)]; Vector3 val = ((Component)obj).transform.position + Vector3.up * (1f + (float)i * 0.03f); Quaternion val2 = ((Component)obj).transform.rotation * entry.Item.spawnRotationOffset; if (SemiFunc.IsMultiplayer()) { PhotonNetwork.InstantiateRoomObject(entry.Item.prefab.ResourcePath, val, val2, (byte)0, (object[])null); } else { Object.Instantiate<GameObject>(entry.Item.prefab.Prefab, val, val2); } num++; } _state.PushToast($"Spawned {num} '{entry.DisplayName}' item(s)."); } private void SpawnValuableEntry(SectorSpawnEntry entry, int count) { //IL_007f: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) if (entry.PrefabRef == null || !entry.PrefabRef.IsValid()) { _state.PushToast("Valuable '" + entry.DisplayName + "' is missing a valid prefab reference."); return; } List<LevelPoint> list = SectorGame.GetSpawnPoints(count).ToList(); if (list.Count == 0) { _state.PushToast("No usable level points are available yet."); return; } int num = 0; for (int i = 0; i < count; i++) { LevelPoint val = list[Mathf.Min(i, list.Count - 1)]; Vector3 val2 = ((Component)val).transform.position + Vector3.up * (1f + (float)i * 0.04f); GameObject obj = (SemiFunc.IsMultiplayer() ? PhotonNetwork.InstantiateRoomObject(entry.PrefabRef.ResourcePath, val2, ((Component)val).transform.rotation, (byte)0, (object[])null) : Object.Instantiate<GameObject>(entry.PrefabRef.Prefab, val2, ((Component)val).transform.rotation)); if (obj != null) { ValuableObject component = obj.GetComponent<ValuableObject>(); if (component != null) { component.DollarValueSetLogic(); } } num++; } _state.PushToast($"Spawned {num} '{entry.DisplayName}' valuable(s)."); } private bool EnsureHostTools(string label) { if (!SectorGame.IsInPlayableRun()) { _state.PushToast("Start or join a live run before using " + label + "."); return false; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { _state.PushToast(label + " is host or singleplayer only."); return false; } return true; } private void SwitchToSpecificLevel(Level? level) { if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)level == (Object)null) { _state.PushToast("That level target is unavailable."); return; } string levelDisplayName = GetLevelDisplayName(level); SectorAccess.SetRunDebugLevel(RunManager.instance, level); try { RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)0); } finally { SectorAccess.SetRunDebugLevel(RunManager.instance, null); } _state.PushToast("Switching to " + levelDisplayName + "."); } private bool EnsureCurrencyTools() { if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)StatsManager.instance == (Object)null) { _state.PushToast("Cash controls are unavailable right now."); return false; } if (SemiFunc.IsMainMenu() && !SemiFunc.RunIsLobbyMenu()) { _state.PushToast("Join a lobby or start singleplayer before editing cash."); return false; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { _state.PushToast("Cash editing is host or singleplayer only."); return false; } return true; } private static Level? FindLevelMatch(string target) { string target2 = target; if (RunManager.instance?.levels == null) { return null; } Level val = ((IEnumerable<Level>)RunManager.instance.levels).FirstOrDefault((Func<Level, bool>)((Level level) => LevelMatches(level, target2, allowPartial: false))); if ((Object)(object)val != (Object)null) { return val; } return ((IEnumerable<Level>)RunManager.instance.levels).FirstOrDefault((Func<Level, bool>)((Level level) => LevelMatches(level, target2, allowPartial: true))); } private static bool LevelMatches(Level? level, string target, bool allowPartial) { if ((Object)(object)level == (Object)null) { return false; } string value = target.Trim().ToLowerInvariant(); if (string.IsNullOrEmpty(value)) { return false; } foreach (string item in EnumerateLevelTerms(level)) { string text = item.ToLowerInvariant(); if (text.Equals(value, StringComparison.Ordinal)) { return true; } if (allowPartial && text.Contains(value, StringComparison.Ordinal)) { return true; } } return false; } private static IEnumerable<string> EnumerateLevelTerms(Level? level) { if (!((Object)(object)level == (Object)null)) { string text = level.NarrativeName?.Trim(); if (!string.IsNullOrEmpty(text)) { yield return text; } string text2 = CleanLevelName(((Object)level).name); if (!string.IsNullOrEmpty(text2)) { yield return text2; } string text3 = ((Object)level).name?.Trim(); if (!string.IsNullOrEmpty(text3)) { yield return text3; } } } private static string GetLevelDisplayName(Level? level) { if ((Object)(object)level == (Object)null) { return "Unknown level"; } string text = level.NarrativeName?.Trim(); if (!string.IsNullOrEmpty(text)) { return text; } string text2 = CleanLevelName(((Object)level).name); if (!string.IsNullOrEmpty(text2)) { return text2; } return "Unknown level"; } private static string CleanLevelName(string? rawName) { string text = (rawName ?? string.Empty).Trim(); if (!text.StartsWith("Level - ", StringComparison.OrdinalIgnoreCase)) { return text; } return text.Substring("Level - ".Length).Trim(); } private static bool ParseToggle(string token, bool currentValue) { switch (token.ToLowerInvariant()) { case "1": case "enabled": case "on": case "true": case "enable": return true; case "0": case "disable": case "off": case "false": case "disabled": return false; default: return !currentValue; } } private static bool TryParseKind(string token, out SectorSpawnKind kind) { switch (token.ToLowerInvariant()) { case "enemy": case "enemies": kind = SectorSpawnKind.Enemy; return true; case "item": case "items": kind = SectorSpawnKind.Item; return true; case "valuable": case "valuables": kind = SectorSpawnKind.Valuable; return true; default: kind = SectorSpawnKind.Enemy; return false; } } } internal static class SectorGame { public static bool IsInPlayableRun() { if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)LevelGenerator.Instance == (Object)null) { return false; } if (!LevelGenerator.Instance.Generated) { return false; } if (SemiFunc.IsMainMenu() || SemiFunc.RunIsLobbyMenu() || SemiFunc.RunIsTutorial()) { return false; } return true; } public static PlayerAvatar? GetLocalPlayer() { PlayerAvatar controllerAvatar = SectorAccess.GetControllerAvatar(PlayerController.instance); if ((Object)(object)controllerAvatar != (Object)null) { return controllerAvatar; } return PlayerAvatar.instance; } public static IEnumerable<PlayerAvatar> GetPlayers() { return SemiFunc.PlayerGetList() ?? new List<PlayerAvatar>(); } public static IEnumerable<LevelPoint> GetSpawnPoints(int desiredCount) { //IL_0029: 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_002e: Unknown result type (might be due to invalid IL or missing references) if (!IsInPlayableRun()) { return Array.Empty<LevelPoint>(); } PlayerAvatar? localPlayer = GetLocalPlayer(); Vector3 anchor = ((localPlayer != null) ? ((Component)localPlayer).transform.position : Vector3.zero); List<LevelPoint> list = SemiFunc.LevelPointsGetAll(); if (list == null || list.Count == 0) { return Array.Empty<LevelPoint>(); } return (from point in list where (Object)(object)point != (Object)null orderby Vector3.Distance(((Component)point).transform.position, anchor) select point).Take(Mathf.Max(desiredCount, 1)).ToList(); } } internal sealed class SectorCatalog { private static readonly Regex EnemyPrefix = new Regex("^Enemy (- )?", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex ItemPrefix = new Regex("^Item ", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex ValuablePrefix = new Regex("^Valuable ", RegexOptions.IgnoreCase | RegexOptions.Compiled); private readonly ManualLogSource _logger; private readonly List<SectorSpawnEntry> _entries = new List<SectorSpawnEntry>(); private float _nextRefreshTime; public int EnemyCount => _entries.Count((SectorSpawnEntry entry) => entry.Kind == SectorSpawnKind.Enemy); public int ItemCount => _entries.Count((SectorSpawnEntry entry) => entry.Kind == SectorSpawnKind.Item); public int ValuableCount => _entries.Count((SectorSpawnEntry entry) => entry.Kind == SectorSpawnKind.Valuable); public SectorCatalog(ManualLogSource logger) { _logger = logger; } public IReadOnlyList<SectorSpawnEntry> GetEntries(SectorSpawnKind kind, string search) { RefreshIfNeeded(); string text = (search ?? string.Empty).Trim(); if (string.IsNullOrEmpty(text)) { return (from entry in _entries where entry.Kind == kind orderby entry.DisplayName select entry).ToList(); } string normalized = text.ToLowerInvariant(); return (from entry in _entries where entry.Kind == kind && entry.SearchText.Contains(normalized, StringComparison.Ordinal) orderby entry.DisplayName select entry).ToList(); } public SectorSpawnEntry? FindBestMatch(SectorSpawnKind kind, string query) { RefreshIfNeeded(); if (string.IsNullOrWhiteSpace(query)) { return null; } string trimmed = query.Trim(); string lowered = trimmed.ToLowerInvariant(); SectorSpawnEntry sectorSpawnEntry = _entries.FirstOrDefault((SectorSpawnEntry entry) => entry.Kind == kind && (entry.Key.Equals(lowered, StringComparison.Ordinal) || entry.DisplayName.Equals(trimmed, StringComparison.OrdinalIgnoreCase))); if (sectorSpawnEntry != null) { return sectorSpawnEntry; } return (from entry in _entries where entry.Kind == kind orderby entry.DisplayName select entry).FirstOrDefault((SectorSpawnEntry entry) => entry.Key.StartsWith(lowered, StringComparison.Ordinal) || entry.SearchText.Contains(lowered, StringComparison.Ordinal)); } private void RefreshIfNeeded() { if (_entries.Count == 0 || !(Time.unscaledTime < _nextRefreshTime)) { _nextRefreshTime = Time.unscaledTime + 2.5f; BuildCatalog(); } } private void BuildCatalog() { _entries.Clear(); try { BuildEnemyEntries(); BuildItemEntries(); BuildValuableEntries(); } catch (Exception ex) { _logger.LogError((object)ex); } } private void BuildEnemyEntries() { if ((Object)(object)EnemyDirector.instance == (Object)null) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (EnemySetup item in Enumerate(EnemyDirector.instance.enemiesDifficulty1).Concat(Enumerate(EnemyDirector.instance.enemiesDifficulty2)).Concat(Enumerate(EnemyDirector.instance.enemiesDifficulty3))) { if (!((Object)(object)item == (Object)null)) { string text = CleanEnemyName(((Object)item).name); string text2 = text.ToLowerInvariant(); if (hashSet.Add(text2)) { _entries.Add(new SectorSpawnEntry(SectorSpawnKind.Enemy, text2, text, "Enemy profile", BuildSearchText(text, ((Object)item).name, "enemy"), item)); } } } } private void BuildItemEntries() { if ((Object)(object)StatsManager.instance == (Object)null) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (Item value in StatsManager.instance.itemDictionary.Values) { if (!((Object)(object)value == (Object)null) && !value.disabled) { string text = CleanItemName(((Object)value).name); string text2 = text.ToLowerInvariant(); if (hashSet.Add(text2)) { _entries.Add(new SectorSpawnEntry(SectorSpawnKind.Item, text2, text, ((object)(itemType)(ref value.itemType)).ToString(), BuildSearchText(text, value.itemName, value.description, ((object)(itemType)(ref value.itemType)).ToString(), "item"), null, value)); } } } } private void BuildValuableEntries() { if ((Object)(object)RunManager.instance == (Object)null || RunManager.instance.levels == null) { return; } HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (Level level in RunManager.instance.levels) { if ((Object)(object)level == (Object)null || level.ValuablePresets == null) { continue; } foreach (LevelValuables valuablePreset in level.ValuablePresets) { foreach (PrefabRef item in EnumerateValuables(valuablePreset)) { if (item != null && item.IsValid()) { string text = CleanValuableName(item.PrefabName); string text2 = text.ToLowerInvariant(); if (hashSet.Add(text2)) { _entries.Add(new SectorSpawnEntry(SectorSpawnKind.Valuable, text2, text, level.NarrativeName, BuildSearchText(text, item.PrefabName, level.NarrativeName, "valuable"), null, null, item)); } } } } } } private static IEnumerable<T> Enumerate<T>(IEnumerable<T>? source) { return source ?? Array.Empty<T>(); } private static IEnumerable<PrefabRef> EnumerateValuables(LevelValuables? preset) { if ((Object)(object)preset == (Object)null) { yield break; } foreach (PrefabRef item in Enumerate(preset.tiny)) { yield return item; } foreach (PrefabRef item2 in Enumerate(preset.small)) { yield return item2; } foreach (PrefabRef item3 in Enumerate(preset.medium)) { yield return item3; } foreach (PrefabRef item4 in Enumerate(preset.big)) { yield return item4; } foreach (PrefabRef item5 in Enumerate(preset.wide)) { yield return item5; } foreach (PrefabRef item6 in Enumerate(preset.tall)) { yield return item6; } foreach (PrefabRef item7 in Enumerate(preset.veryTall)) { yield return item7; } } private static string BuildSearchText(params string?[] fragments) { return string.Join(" ", fragments.Where((string fragment) => !string.IsNullOrWhiteSpace(fragment))).ToLowerInvariant(); } private static string CleanEnemyName(string rawName) { return EnemyPrefix.Replace(rawName ?? string.Empty, string.Empty).Trim(); } private static string CleanItemName(string rawName) { return ItemPrefix.Replace(rawName ?? string.Empty, string.Empty).Trim(); } private static string CleanValuableName(string rawName) { return ValuablePrefix.Replace(rawName ?? string.Empty, string.Empty).Trim(); } } internal enum SectorTab { Ops, Spawn, Players, World, Scene } internal enum SectorSpawnKind { Enemy, Item, Valuable } internal sealed class SectorSpawnEntry { public SectorSpawnKind Kind { get; } public string Key { get; } public string DisplayName { get; } public string Subtitle { get; } public string SearchText { get; } public EnemySetup? EnemySetup { get; } public Item? Item { get; } public PrefabRef? PrefabRef { get; } public SectorSpawnEntry(SectorSpawnKind kind, string key, string displayName, string subtitle, string searchText, EnemySetup? enemySetup = null, Item? item = null, PrefabRef? prefabRef = null) { Kind = kind; Key = key; DisplayName = displayName; Subtitle = subtitle; SearchText = searchText; EnemySetup = enemySetup; Item = item; PrefabRef = prefabRef; } } internal sealed class SectorOverlayState { private readonly List<string> _activity = new List<string>(); public bool Visible; public Rect WindowRect = new Rect(72f, 72f, 1180f, 720f); public SectorTab ActiveTab; public SectorSpawnKind ActiveSpawnKind; public Vector2 OpsScroll; public Vector2 SpawnScroll; public Vector2 PlayersScroll; public Vector2 WorldScroll; public Vector2 SceneScroll; public string SpawnSearch = string.Empty; public string CommandText = string.Empty; public string SpawnAmountText = "1"; public string ObjectSearch = string.Empty; public string LevelSwitchText = string.Empty; public string MoneyAddText = "1000"; public bool GodMode; public bool InfiniteEnergy; public bool InfiniteStrength; public bool StickyBoost; public bool NoAggro; public float SpeedMultiplier = 2f; public bool ShowLevelPoints; public bool ShowMeshLabels; public bool ShowMeshBounds; public int SelectedSceneObjectId; public string FlashMessage = string.Empty; public float FlashUntil; public IReadOnlyList<string> Activity => _activity; public int SpawnAmount { get { if (int.TryParse(SpawnAmountText, out var result)) { return Mathf.Clamp(result, 1, 25); } return 1; } } public void PushToast(string message) { if (!string.IsNullOrWhiteSpace(message)) { FlashMessage = message.Trim(); FlashUntil = Time.unscaledTime + 4.5f; _activity.Insert(0, $"[{DateTime.Now:HH:mm:ss}] {FlashMessage}"); if (_activity.Count > 10) { _activity.RemoveRange(10, _activity.Count - 10); } } } } internal readonly struct SectorRuntimeSnapshot { public bool InRun { get; } public bool IsHost { get; } public string LevelName { get; } public int Players { get; } public int AlivePlayers { get; } public int DeadPlayers { get; } public int Enemies { get; } public int Valuables { get; } public int LocalHealth { get; } public int LocalMaxHealth { get; } public float LocalEnergy { get; } public float LocalEnergyMax { get; } public bool NoAggroEnabled { get; } public SectorRuntimeSnapshot(bool inRun, bool isHost, string levelName, int players, int alivePlayers, int deadPlayers, int enemies, int valuables, int localHealth, int localMaxHealth, float localEnergy, float localEnergyMax, bool noAggroEnabled) { InRun = inRun; IsHost = isHost; LevelName = levelName; Players = players; AlivePlayers = alivePlayers; DeadPlayers = deadPlayers; Enemies = enemies; Valuables = valuables; LocalHealth = localHealth; LocalMaxHealth = localMaxHealth; LocalEnergy = localEnergy; LocalEnergyMax = localEnergyMax; NoAggroEnabled = noAggroEnabled; } } internal readonly struct SectorSceneSnapshot { public bool FreecamActive { get; } public bool CopyForgeActive { get; } public int TrackedObjects { get; } public int LevelPoints { get; } public int MeshObjects { get; } public string ModeLabel { get; } public SectorSceneSnapshot(bool freecamActive, bool copyForgeActive, int trackedObjects, int levelPoints, int meshObjects, string modeLabel) { FreecamActive = freecamActive; CopyForgeActive = copyForgeActive; TrackedObjects = trackedObjects; LevelPoints = levelPoints; MeshObjects = meshObjects; ModeLabel = modeLabel; } } internal sealed class SectorSceneObjectInfo { public int InstanceId { get; } public string Name { get; } public string Path { get; } public string Category { get; } public Vector3 Position { get; } public bool Active { get; } public int RendererCount { get; } public bool HasCollider { get; } public bool HasPhotonView { get; } public bool CanDelete { get; } public bool CanCopy { get; } public SectorSceneObjectInfo(int instanceId, string name, string path, string category, Vector3 position, bool active, int rendererCount, bool hasCollider, bool hasPhotonView, bool canDelete, bool canCopy) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) InstanceId = instanceId; Name = name; Path = path; Category = category; Position = position; Active = active; RendererCount = rendererCount; HasCollider = hasCollider; HasPhotonView = hasPhotonView; CanDelete = canDelete; CanCopy = canCopy; } } internal sealed class SectorSceneQueryResult { public IReadOnlyList<SectorSceneObjectInfo> Entries { get; } public int TotalMatches { get; } public SectorSceneQueryResult(IReadOnlyList<SectorSceneObjectInfo> entries, int totalMatches) { Entries = entries; TotalMatches = totalMatches; } } [BepInPlugin("empress.repo.sector", "Sector", "0.1.0")] internal sealed class SectorPlugin : BaseUnityPlugin { internal const string PluginGuid = "empress.repo.sector"; internal const string PluginName = "Sector"; internal const string PluginVersion = "0.1.0"; private ConfigEntry<KeyboardShortcut>? _toggleKey; private SectorOverlayState? _state; private SectorCatalog? _catalog; private SectorActions? _actions; private SectorSceneController? _scene; private SectorUi? _ui; private bool _cursorCaptured; private bool _previousCursorVisible; private CursorLockMode _previousCursorLockState; private Texture2D? _sectorCursorTexture; private void Awake() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); _toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Input", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Toggle the Sector control window."); _state = new SectorOverlayState(); _catalog = new SectorCatalog(((BaseUnityPlugin)this).Logger); _actions = new SectorActions(((BaseUnityPlugin)this).Logger, _state, _catalog); _scene = new SectorSceneController(((BaseUnityPlugin)this).Logger, _state); _ui = new SectorUi(((BaseUnityPlugin)this).Logger, _state, _catalog, _actions, _scene, _toggleKey.Value); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Sector booted. Press F8 to open the Empress control suite."); } private void Update() { //IL_0027: 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) if (_state != null && _actions != null && _scene != null && _toggleKey != null) { KeyboardShortcut value = _toggleKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _state.Visible = !_state.Visible; _state.PushToast(_state.Visible ? "Sector window opened." : "Sector window hidden."); } if (_state.Visible && Input.GetKeyDown((KeyCode)27)) { _state.Visible = false; } _actions.Tick(); _scene.Tick(_state.Visible); if (_state.Visible) { ApplySectorCursor(); } else { RestoreCursorState(); } } } private void OnGUI() { _ui?.Draw(); _scene?.DrawOverlay(); } private void OnDestroy() { RestoreCursorState(); _scene?.Reset(); _actions?.ResetLocalPowerState(); } private void CaptureCursorState() { //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) if (!_cursorCaptured) { _previousCursorVisible = Cursor.visible; _previousCursorLockState = Cursor.lockState; _cursorCaptured = true; } } private void RestoreCursorState() { //IL_000a: 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_0034: Unknown result type (might be due to invalid IL or missing references) if (_cursorCaptured) { Cursor.SetCursor((Texture2D)null, Vector2.zero, (CursorMode)0); Cursor.visible = _previousCursorVisible; Cursor.lockState = _previousCursorLockState; if ((_previousCursorVisible || (int)_previousCursorLockState == 0) && (Object)(object)MenuCursor.instance != (Object)null) { MenuCursor.instance.Show(); } _cursorCaptured = false; } } private void ApplySectorCursor() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) CaptureCursorState(); EnsureSectorCursorTexture(); SuppressGameCursorSystems(); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; Cursor.SetCursor(_sectorCursorTexture, new Vector2((float)((Texture)_sectorCursorTexture).width * 0.5f, (float)((Texture)_sectorCursorTexture).height * 0.5f), (CursorMode)0); } private void SuppressGameCursorSystems() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) SectorAccess.SetCursorUnlockTimer(CursorManager.instance, -1234f); if (!((Object)(object)MenuCursor.instance == (Object)null)) { SectorAccess.SetMenuCursorShowTimer(MenuCursor.instance, 0f); SectorAccess.SetMenuCursorOverridePosTimer(MenuCursor.instance, 0f); GameObject menuCursorMesh = SectorAccess.GetMenuCursorMesh(MenuCursor.instance); if ((Object)(object)menuCursorMesh != (Object)null && menuCursorMesh.activeSelf) { menuCursorMesh.SetActive(false); } ((Component)MenuCursor.instance).transform.localScale = Vector3.zero; } } private void EnsureSectorCursorTexture() { //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_002f: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_sectorCursorTexture != (Object)null) { return; } _sectorCursorTexture = new Texture2D(32, 32, (TextureFormat)4, false) { filterMode = (FilterMode)0, hideFlags = (HideFlags)61 }; for (int i = 0; i < ((Texture)_sectorCursorTexture).height; i++) { for (int j = 0; j < ((Texture)_sectorCursorTexture).width; j++) { float num = (float)j - 15.5f; float num2 = (float)i - 15.5f; float num3 = Mathf.Sqrt(num * num + num2 * num2); Color clear = Color.clear; if (num3 <= 2.25f) { ((Color)(ref clear))..ctor(1f, 0.94f, 0.94f, 1f); } else if (num3 <= 5.2f) { ((Color)(ref clear))..ctor(0.98f, 0.22f, 0.16f, 1f); } else if (num3 <= 7.4f) { ((Color)(ref clear))..ctor(1f, 0.2f, 0.16f, 0.4f); } _sectorCursorTexture.SetPixel(j, i, clear); } } _sectorCursorTexture.Apply(); } } internal sealed class SectorSceneController { private readonly struct PlacementState { public Vector3 Position { get; } public Quaternion Rotation { get; } public PlacementState(Vector3 position, Quaternion rotation) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Position = position; Rotation = rotation; } } private const HideFlags RuntimeHideFlags = 61; private const float FreezeRefresh = 0.2f; private const float SceneRefreshInterval = 0.75f; private const int MaxBrowserEntries = 140; private const int MaxLabelEntries = 48; private const int MaxBoundsEntries = 28; private readonly ManualLogSource _logger; private readonly SectorOverlayState _state; private readonly List<SectorSceneObjectInfo> _sceneObjects = new List<SectorSceneObjectInfo>(); private readonly Dictionary<int, WeakReference<GameObject>> _sceneObjectRefs = new Dictionary<int, WeakReference<GameObject>>(); private float _nextSceneRefreshTime; private Transform? _freecamRoot; private Transform? _freecamRestoreParent; private Vector3 _freecamRestoreLocalPosition; private Quaternion _freecamRestoreLocalRotation; private float _freecamYaw; private float _freecamPitch; private bool _freecamActive; private int _copySourceId; private string _copySourceName = string.Empty; private GameObject? _copyPreview; private float _copyDistance = 5f; private float _copyHeightOffset; private Vector3 _copyRotationEuler; private GUIStyle? _overlayLabelStyle; private GUIStyle? _overlayHintStyle; private Texture2D? _overlayLineTexture; private Texture2D? _blueOrbGlowTexture; private Texture2D? _blueOrbCoreTexture; private Texture2D? _orangeOrbGlowTexture; private Texture2D? _orangeOrbCoreTexture; private GameObject? _worldVisualRoot; private Material? _worldLineMaterial; private Material? _worldOrbMaterial; private readonly List<LineRenderer> _worldLinePool = new List<LineRenderer>(); private readonly List<GameObject> _worldOrbPool = new List<GameObject>(); private bool IsCopyForgeActive { get { if ((Object)(object)_copyPreview != (Object)null) { return _copySourceId != 0; } return false; } } public SectorSceneController(ManualLogSource logger, SectorOverlayState state) { _logger = logger; _state = state; } public SectorSceneSnapshot GetSnapshot() { RefreshSceneCache(); List<LevelPoint> list = SemiFunc.LevelPointsGetAll(); int meshObjects = _sceneObjects.Count((SectorSceneObjectInfo info) => info.RendererCount > 0); string modeLabel = (IsCopyForgeActive ? ("COPY FORGE: " + _copySourceName) : (_freecamActive ? "FREECAM ACTIVE" : "SCENE TOOLING READY")); return new SectorSceneSnapshot(_freecamActive, IsCopyForgeActive, _sceneObjects.Count, list?.Count ?? 0, meshObjects, modeLabel); } public SectorSceneQueryResult QueryObjects(string search) { RefreshSceneCache(); IEnumerable<SectorSceneObjectInfo> source = _sceneObjects; string text = (search ?? string.Empty).Trim(); if (!string.IsNullOrEmpty(text)) { string lowered = text.ToLowerInvariant(); source = source.Where((SectorSceneObjectInfo info) => info.Name.Contains(lowered, StringComparison.OrdinalIgnoreCase) || info.Path.Contains(lowered, StringComparison.OrdinalIgnoreCase) || info.Category.Contains(lowered, StringComparison.OrdinalIgnoreCase)); } List<SectorSceneObjectInfo> list = source.ToList(); return new SectorSceneQueryResult(list.Take(140).ToList(), list.Count); } public SectorSceneObjectInfo? GetSelectedObject() { if (_state.SelectedSceneObjectId == 0) { return null; } GameObject val = ResolveSceneObject(_state.SelectedSceneObjectId); if (!((Object)(object)val == (Object)null)) { return BuildSceneInfo(val); } return null; } public void Tick(bool menuVisible) { try { if (!SectorGame.IsInPlayableRun()) { SetWorldVisualsVisible(visible: false); if (_freecamActive || IsCopyForgeActive) { Reset(); } return; } if (menuVisible || _freecamActive || IsCopyForgeActive) { KeepPlayerFrozen(); } if (IsCopyForgeActive) { EnsureFreecamCamera(); UpdateFreecamMotion(menuVisible); UpdateCopyForge(menuVisible); } else if (_freecamActive) { EnsureFreecamCamera(); UpdateFreecamMotion(menuVisible); if (!menuVisible && Input.GetKeyDown((KeyCode)27)) { ExitFreecam(); _state.PushToast("Freecam disengaged."); } } else if ((Object)(object)_freecamRoot != (Object)null) { RestoreMainCamera(); } UpdateWorldVisuals(); } catch (Exception ex) { _logger.LogError((object)ex); Reset(); _state.PushToast("Scene tooling hit an error and reset safely."); } } public void DrawOverlay() { if (SectorGame.IsInPlayableRun()) { EnsureOverlayStyles(); if (_freecamActive) { DrawHintBox(IsCopyForgeActive ? ("COPY FORGE: " + _copySourceName + " | Left Click place | Right Click / Esc cancel | Mouse Wheel distance | Q/E rotate | R/F height") : "FREECAM ACTIVE | WASD move | Space / Ctrl vertical | Shift boost | Esc exit | F8 reopen Sector", 16f); } _ = IsCopyForgeActive; } } public void ToggleFreecam() { if (_freecamActive) { bool isCopyForgeActive = IsCopyForgeActive; ExitFreecam(); _state.PushToast(isCopyForgeActive ? "Copy forge aborted." : "Freecam disengaged."); } else if (!EnsureFreecamCamera()) { _state.PushToast("Main camera is unavailable for freecam."); } else { _freecamActive = true; _state.Visible = false; _state.PushToast("Freecam engaged. Press F8 to reopen Sector."); } } public void FocusObject(int instanceId) { GameObject val = ResolveSceneObject(instanceId); if ((Object)(object)val == (Object)null) { RefreshSceneCache(force: true); _state.PushToast("That scene object is no longer available."); return; } if (!EnsureFreecamCamera()) { _state.PushToast("Main camera is unavailable for focus jump."); return; } _state.SelectedSceneObjectId = instanceId; _freecamActive = true; PositionFreecamForTarget(val); _state.Visible = false; _state.PushToast("Focused freecam on " + ((Object)val).name + "."); } public void DeleteObject(int instanceId) { GameObject val = ResolveSceneObject(instanceId); if ((Object)(object)val == (Object)null) { RefreshSceneCache(force: true); _state.PushToast("That scene object is already gone."); return; } if (IsProtectedObject(val)) { _state.PushToast(((Object)val).name + " is protected from deletion."); return; } _state.SelectedSceneObjectId = instanceId; try { PhotonView component = val.GetComponent<PhotonView>(); if (SemiFunc.IsMultiplayer() && (Object)(object)component != (Object)null) { PhotonNetwork.Destroy(val); } else { Object.Destroy((Object)(object)val); } RefreshSceneCache(force: true); _state.PushToast("Deleted " + ((Object)val).name + "."); } catch (Exception ex) { _logger.LogError((object)ex); _state.PushToast("Could not delete " + ((Object)val).name + "."); } } public void BeginCopyForge(int instanceId) { //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) GameObject val = ResolveSceneObject(instanceId); if ((Object)(object)val == (Object)null) { RefreshSceneCache(force: true); _state.PushToast("That scene object is no longer available."); return; } if (!HasRenderableGeometry(val)) { _state.PushToast(((Object)val).name + " has no visible mesh data to forge from."); return; } if (SemiFunc.IsMultiplayer()) { _state.PushToast("Copy forge creates a local visual clone in multiplayer right now."); } if (!EnsureFreecamCamera()) { _state.PushToast("Main camera is unavailable for copy forge."); return; } ClearCopyForgeState(); GameObject val2 = CreateVisualClone(val, preview: true); if ((Object)(object)val2 == (Object)null) { _state.PushToast("Could not build a forge preview for " + ((Object)val).name + "."); return; } _state.SelectedSceneObjectId = 0; _copySourceId = instanceId; _copySourceName = ((Object)val).name; _copyPreview = val2; _copyHeightOffset = 0f; Quaternion rotation = val.transform.rotation; _copyRotationEuler = ((Quaternion)(ref rotation)).eulerAngles; _copyDistance = Mathf.Clamp(GetSuggestedDistance(val), 2.2f, 14f); _freecamActive = true; PositionFreecamForTarget(val); _state.Visible = false; _state.PushToast("Copy forge armed for " + ((Object)val).name + "."); } public void Reset() { ClearCopyForgeState(); _freecamActive = false; RestoreMainCamera(); SetWorldVisualsVisible(visible: false); } private void UpdateWorldVisuals() { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) if (!SectorGame.IsInPlayableRun() || IsCopyForgeActive) { SetWorldVisualsVisible(visible: false); return; } bool flag = _state.SelectedSceneObjectId != 0; if (!(_state.ShowLevelPoints || _state.ShowMeshLabels || _state.ShowMeshBounds || flag)) { SetWorldVisualsVisible(visible: false); return; } EnsureWorldVisualRoot(); SetWorldVisualsVisible(visible: true); int lineIndex = 0; int orbIndex = 0; if (_state.ShowLevelPoints) { HashSet<ulong> hashSet = new HashSet<ulong>(); foreach (LevelPoint item2 in EnumerateLevelPointLabels().Take(48)) { if ((Object)(object)item2 == (Object)null) { continue; } AddWorldOrb(ref orbIndex, ((Component)item2).transform.position + Vector3.up * 0.08f, 0.2f); foreach (LevelPoint connectedPoint in item2.ConnectedPoints) { if (!((Object)(object)connectedPoint == (Object)null)) { int instanceID = ((Object)item2).GetInstanceID(); int instanceID2 = ((Object)connectedPoint).GetInstanceID(); uint num = (uint)Mathf.Min(instanceID, instanceID2); uint num2 = (uint)Mathf.Max(instanceID, instanceID2); ulong item = ((ulong)num << 32) | num2; if (hashSet.Add(item)) { AddWorldLine(ref lineIndex, ((Component)item2).transform.position + Vector3.up * 0.06f, ((Component)connectedPoint).transform.position + Vector3.up * 0.06f, new Color(0.35f, 0.84f, 1f, 0.92f), 0.045f); } } } } } if (_state.ShowMeshLabels || _state.ShowMeshBounds) { RefreshSceneCache(); } if (_state.ShowMeshLabels) { Vector3 start = default(Vector3); Vector3 end = default(Vector3); foreach (SectorSceneObjectInfo item3 in _sceneObjects.Where((SectorSceneObjectInfo entry) => entry.RendererCount > 0).Take(48)) { GameObject val = ResolveSceneObject(item3.InstanceId); if (!((Object)(object)val == (Object)null) && TryGetWorldBounds(val, out var bounds)) { ((Vector3)(ref start))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).center.z); ((Vector3)(ref end))..ctor(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).center.z); AddWorldLine(ref lineIndex, start, end, new Color(1f, 0.42f, 0.18f, 0.9f), 0.03f); Vector3 extents = ((Bounds)(ref bounds)).extents; float num3 = Mathf.Clamp(((Vector3)(ref extents)).magnitude * 0.1f, 0.1f, 0.32f); AddWorldLine(ref lineIndex, ((Bounds)(ref bounds)).center + Vector3.left * num3, ((Bounds)(ref bounds)).center + Vector3.right * num3, new Color(1f, 0.42f, 0.18f, 0.82f), 0.026f); AddWorldLine(ref lineIndex, ((Bounds)(ref bounds)).center + Vector3.forward * num3, ((Bounds)(ref bounds)).center + Vector3.back * num3, new Color(1f, 0.42f, 0.18f, 0.82f), 0.026f); AddWorldLine(ref lineIndex, ((Bounds)(ref bounds)).center + Vector3.up * num3, ((Bounds)(ref bounds)).center + Vector3.down * num3, new Color(1f, 0.42f, 0.18f, 0.82f), 0.026f); } } } if (_state.ShowMeshBounds) { foreach (SectorSceneObjectInfo item4 in _sceneObjects.Where((SectorSceneObjectInfo entry) => entry.RendererCount > 0).Take(28)) { GameObject val2 = ResolveSceneObject(item4.InstanceId); if ((Object)(object)val2 != (Object)null && TryGetWorldBounds(val2, out var bounds2)) { AddWorldBoundsBox(ref lineIndex, ExpandBounds(bounds2), new Color(1f, 0.34f, 0.19f, 0.88f), 0.024f); } } } GameObject val3 = ResolveSceneObject(_state.SelectedSceneObjectId); if ((Object)(object)val3 != (Object)null && TryGetWorldBounds(val3, out var bounds3)) { AddWorldBoundsBox(ref lineIndex, ExpandBounds(bounds3), new Color(1f, 0.92f, 0.36f, 0.96f), 0.032f); } TrimWorldVisualPools(lineIndex, orbIndex); } private void EnsureWorldVisualRoot() { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown if (!((Object)(object)_worldVisualRoot != (Object)null)) { _worldVisualRoot = new GameObject("Sector.WorldVisuals") { hideFlags = (HideFlags)61, layer = 2 }; Object.DontDestroyOnLoad((Object)(object)_worldVisualRoot); ApplyRuntimeHideFlags(_worldVisualRoot); } } private void SetWorldVisualsVisible(bool visible) { if ((Object)(object)_worldVisualRoot != (Object)null) { _worldVisualRoot.SetActive(visible); } } private void TrimWorldVisualPools(int usedLines, int usedOrbs) { for (int i = usedLines; i < _worldLinePool.Count; i++) { if ((Object)(object)_worldLinePool[i] != (Object)null) { ((Component)_worldLinePool[i]).gameObject.SetActive(false); } } for (int j = usedOrbs; j < _worldOrbPool.Count; j++) { if ((Object)(object)_worldOrbPool[j] != (Object)null) { _worldOrbPool[j].SetActive(false); } } } private void AddWorldOrb(ref int orbIndex, Vector3 position, float scale) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) GameObject orCreateWorldOrb = GetOrCreateWorldOrb(orbIndex++); orCreateWorldOrb.transform.position = position; orCreateWorldOrb.transform.rotation = Quaternion.identity; orCreateWorldOrb.transform.localScale = Vector3.one * scale; orCreateWorldOrb.SetActive(true); } private void AddWorldLine(ref int lineIndex, Vector3 start, Vector3 end, Color color, float width) { //IL_0024: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) LineRenderer orCreateWorldLine = GetOrCreateWorldLine(lineIndex++); ((Component)orCreateWorldLine).gameObject.SetActive(true); orCreateWorldLine.widthMultiplier = width; orCreateWorldLine.startColor = color; orCreateWorldLine.endColor = color; orCreateWorldLine.positionCount = 2; orCreateWorldLine.SetPosition(0, start); orCreateWorldLine.SetPosition(1, end); } private void AddWorldBoundsBox(ref int lineIndex, Bounds bounds, Color color, float width) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //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_0012: 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_001e: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_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_0050: 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_0063: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) Vector3 min = ((Bounds)(ref bounds)).min; Vector3 max = ((Bounds)(ref bounds)).max; Vector3 start = default(Vector3); ((Vector3)(ref start))..ctor(min.x, min.y, min.z); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(min.x, min.y, max.z); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(min.x, max.y, min.z); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(min.x, max.y, max.z); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(max.x, min.y, min.z); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(max.x, min.y, max.z); Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor(max.x, max.y, min.z); Vector3 end = default(Vector3); ((Vector3)(ref end))..ctor(max.x, max.y, max.z); AddWorldLine(ref lineIndex, start, val, color, width); AddWorldLine(ref lineIndex, start, val2, color, width); AddWorldLine(ref lineIndex, start, val4, color, width); AddWorldLine(ref lineIndex, val, val3, color, width); AddWorldLine(ref lineIndex, val, val5, color, width); AddWorldLine(ref lineIndex, val2, val3, color, width); AddWorldLine(ref lineIndex, val2, val6, color, width); AddWorldLine(ref lineIndex, val4, val5, color, width); AddWorldLine(ref lineIndex, val4, val6, color, width); AddWorldLine(ref lineIndex, val3, end, color, width); AddWorldLine(ref lineIndex, val5, end, color, width); AddWorldLine(ref lineIndex, val6, end, color, width); } private LineRenderer GetOrCreateWorldLine(int index) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown while (_worldLinePool.Count <= index) { EnsureWorldVisualRoot(); GameObject val = new GameObject($"SectorLine.{_worldLinePool.Count}") { hideFlags = (HideFlags)61, layer = 2 }; val.transform.SetParent(_worldVisualRoot.transform, false); LineRenderer val2 = val.AddComponent<LineRenderer>(); ((Renderer)val2).sharedMaterial = GetWorldLineMaterial(); val2.useWorldSpace = true; val2.loop = false; val2.alignment = (LineAlignment)0; val2.textureMode = (LineTextureMode)0; val2.numCapVertices = 4; val2.numCornerVertices = 4; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).motionVectorGenerationMode = (MotionVectorGenerationMode)2; ((Renderer)val2).enabled = true; ApplyRuntimeHideFlags(val); val.SetActive(false); _worldLinePool.Add(val2); } return _worldLinePool[index]; } private GameObject GetOrCreateWorldOrb(int index) { while (_worldOrbPool.Count <= index) { EnsureWorldVisualRoot(); GameObject val = GameObject.CreatePrimitive((PrimitiveType)0); ((Object)val).name = $"SectorLevelPoint.{_worldOrbPool.Count}"; ((Object)val).hideFlags = (HideFlags)61; val.layer = 2; val.transform.SetParent(_worldVisualRoot.transform, false); Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { component.enabled = false; Object.Destroy((Object)(object)component); } MeshRenderer component2 = val.GetComponent<MeshRenderer>(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).sharedMaterial = GetWorldOrbMaterial(); ((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component2).receiveShadows = false; ((Renderer)component2).lightProbeUsage = (LightProbeUsage)0; ((Renderer)component2).reflectionProbeUsage = (ReflectionProbeUsage)0; ((Renderer)component2).motionVectorGenerationMode = (MotionVectorGenerationMode)2; } ApplyRuntimeHideFlags(val); val.SetActive(false); _worldOrbPool.Add(val); } return _worldOrbPool[index]; } private Material GetWorldLineMaterial() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown if ((Object)(object)_worldLineMaterial != (Object)null) { return _worldLineMaterial; } Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard"); _worldLineMaterial = new Material(val) { hideFlags = (HideFlags)61 }; ApplyRuntimeHideFlags((Object)(object)_worldLineMaterial); return _worldLineMaterial; } private Material GetWorldOrbMaterial() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_worldOrbMaterial != (Object)null) { return _worldOrbMaterial; } Shader val = Shader.Find("Standard") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default"); _worldOrbMaterial = new Material(val) { hideFlags = (HideFlags)61 }; _worldOrbMaterial.color = new Color(0.35f, 0.86f, 1f, 0.96f); if (_worldOrbMaterial.HasProperty("_Color")) { _worldOrbMaterial.SetColor("_Color", new Color(0.35f, 0.86f, 1f, 0.96f)); } if (_worldOrbMaterial.HasProperty("_EmissionColor")) { _worldOrbMaterial.EnableKeyword("_EMISSION"); _worldOrbMaterial.SetColor("_EmissionColor", new Color(0.22f, 0.72f, 1f, 1f) * 1.8f); } ApplyRuntimeHideFlags((Object)(object)_worldOrbMaterial); return _worldOrbMaterial; } private static Bounds ExpandBounds(Bounds bounds) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Vector3 extents = ((Bounds)(ref bounds)).extents; ((Bounds)(ref bounds)).Expand(Mathf.Max(0.04f, ((Vector3)(ref extents)).magnitude * 0.02f)); return bounds; } private void RefreshSceneCache(bool force = false) { //IL_005d: 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_0062: Unknown result type (might be due to invalid IL or missing references) if (!force && _sceneObjects.Count != 0 && Time.unscaledTime < _nextSceneRefreshTime) { return; } _nextSceneRefreshTime = Time.unscaledTime + 0.75f; _sceneObjects.Clear(); _sceneObjectRefs.Clear(); Transform? cameraTransform = GetCameraTransform(); Vector3 anchor = ((cameraTransform != null) ? cameraTransform.position : Vector3.zero); Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsSortMode)0); foreach (Transform val in array) { GameObject val2 = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); if (!((Object)(object)val2 == (Object)null) && ShouldIncludeObject(val2)) { SectorSceneObjectInfo sectorSceneObjectInfo = BuildSceneInfo(val2); _sceneObjects.Add(sectorSceneObjectInfo); _sceneObjectRefs[sectorSceneObjectInfo.InstanceId] = new WeakReference<GameObject>(val2); } } _sceneObjects.Sort(delegate(SectorSceneObjectInfo left, SectorSceneObjectInfo right) { //IL_001c: 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_0027: 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_0039: Unknown result type (might be due to invalid