using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Logging;
using Dungeonator;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("GungeonUnstuck")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GungeonUnstuck")]
[assembly: AssemblyTitle("GungeonUnstuck")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace GungeonUnstuck;
[BepInPlugin("silstrom.gungeonunstuck", "GungeonUnstuck", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
private sealed class RescueResult
{
public int ClearedPlayers;
public int RecoveredLeeks;
public int CompletedBossDeaths;
public int FixedRooms;
public int UnsealedRooms;
public int TriggeredRewards;
}
private sealed class OpenRoomResult
{
public int Rooms;
public int IgnoredEnemies;
public int DoorsUnsealed;
public int DoorsUnlocked;
public int DoorsOpened;
public int BlockersUnsealed;
public int TeleportersRestored;
public int MinimapRoomsRevealed;
}
public const string PluginGuid = "silstrom.gungeonunstuck";
public const string PluginName = "GungeonUnstuck";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource Log;
private static readonly string[] UiReasons = new string[13]
{
"dragun",
"dragun_transition",
"generic",
"BossIntro",
"bossKillCam",
"gm_pause",
"pause",
"conversation",
"conversationBar",
"minimap",
"punchout",
"metal gear",
string.Empty
};
private void Awake()
{
Log = ((BaseUnityPlugin)this).Logger;
((BaseUnityPlugin)this).Logger.LogInfo((object)"GungeonUnstuck v1.0.0 loaded");
}
private void Start()
{
ETGModConsole.Commands.AddUnit("unstuck", (Action<string[]>)delegate
{
RescueResult rescueResult = Rescue();
ETGModConsole.Log((object)string.Format("<color=#00FF00>{0}:</color> cleared {1} player(s), recovered {2} Leek item(s), completed {3} stuck boss death(s), fixed {4} room(s), unsealed {5} room(s), triggered {6} reward flow(s).", "GungeonUnstuck", rescueResult.ClearedPlayers, rescueResult.RecoveredLeeks, rescueResult.CompletedBossDeaths, rescueResult.FixedRooms, rescueResult.UnsealedRooms, rescueResult.TriggeredRewards), false);
});
ETGModConsole.Commands.AddUnit("openroom", (Action<string[]>)delegate
{
OpenRoomResult openRoomResult = ForceOpenCurrentRooms();
ETGModConsole.Log((object)string.Format("<color=#00FF00>{0}:</color> force-opened {1} room(s), ignored {2} stuck enemy/enemies, unsealed {3} door(s), unlocked {4} door(s), opened {5} normal door(s), unsealed {6} blocker(s), restored {7} teleporter(s), revealed {8} minimap room(s).", "GungeonUnstuck", openRoomResult.Rooms, openRoomResult.IgnoredEnemies, openRoomResult.DoorsUnsealed, openRoomResult.DoorsUnlocked, openRoomResult.DoorsOpened, openRoomResult.BlockersUnsealed, openRoomResult.TeleportersRestored, openRoomResult.MinimapRoomsRevealed), false);
});
ETGModConsole.Log((object)"GungeonUnstuck v1.0.0 Initialized - commands: unstuck, openroom", false);
}
private static RescueResult Rescue()
{
RescueResult rescueResult = new RescueResult();
try
{
CancelRunningBossKillCams();
EndRunningBossIntros();
ResetGlobalCutsceneState();
rescueResult.ClearedPlayers = ResetPlayers();
rescueResult.RecoveredLeeks = RecoverLeekItems();
ResetCamera();
ResetUI();
ResetMinimap();
ResetScreenFade();
ResetBossHealthBars();
StaticReferenceManager.DestroyAllProjectiles();
rescueResult.CompletedBossDeaths += CompleteStuckDraGunDeaths();
FixCurrentRooms(rescueResult);
}
catch (Exception ex)
{
Log.LogError((object)("unstuck failed: " + ex));
ETGModConsole.Log((object)"<color=#FF0000>GungeonUnstuck failed.</color> Check BepInEx log for details.", false);
}
return rescueResult;
}
private static OpenRoomResult ForceOpenCurrentRooms()
{
OpenRoomResult openRoomResult = new OpenRoomResult();
try
{
ResetGlobalCutsceneState();
RecoverLeekItems();
ResetMinimap();
ResetUI();
List<RoomHandler> roomsToRescue = GetRoomsToRescue();
for (int i = 0; i < roomsToRescue.Count; i++)
{
RoomHandler val = roomsToRescue[i];
if (val != null)
{
openRoomResult.Rooms++;
openRoomResult.IgnoredEnemies += IgnoreRoomClearEnemies(val);
openRoomResult.BlockersUnsealed += ForceOpenRoom(val, openRoomResult);
openRoomResult.TeleportersRestored += RestoreRoomTeleporters(val);
openRoomResult.MinimapRoomsRevealed += (RestoreMinimapRoom(val) ? 1 : 0);
}
}
}
catch (Exception ex)
{
Log.LogError((object)("openroom failed: " + ex));
ETGModConsole.Log((object)"<color=#FF0000>GungeonUnstuck openroom failed.</color> Check BepInEx log for details.", false);
}
return openRoomResult;
}
private static void CancelRunningBossKillCams()
{
BossKillCam[] array = Object.FindObjectsOfType<BossKillCam>();
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] != (Object)null)
{
array[i].ForceCancelSequence();
}
}
BossKillCam.BossDeathCamRunning = false;
}
private static void EndRunningBossIntros()
{
GenericIntroDoer[] array = Object.FindObjectsOfType<GenericIntroDoer>();
FieldInfo fieldInfo = AccessTools.Field(typeof(GenericIntroDoer), "m_isRunning");
MethodInfo methodInfo = AccessTools.Method(typeof(GenericIntroDoer), "EndSequence", new Type[1] { typeof(bool) }, (Type[])null);
if ((object)fieldInfo == null || (object)methodInfo == null)
{
return;
}
foreach (GenericIntroDoer val in array)
{
if (!((Object)(object)val == (Object)null) && (bool)fieldInfo.GetValue(val))
{
methodInfo.Invoke(val, new object[1] { false });
}
}
}
private static void ResetGlobalCutsceneState()
{
if (GameManager.HasInstance)
{
GameManager.Instance.PreventPausing = false;
}
GameManager.IsBossIntro = false;
BossKillCam.BossDeathCamRunning = false;
SuperReaperController.PreventShooting = false;
BraveTime.ClearAllMultipliers();
if ((Object)(object)StickyFrictionManager.Instance != (Object)null)
{
StickyFrictionManager.Instance.FrictionEnabled = true;
}
}
private static int ResetPlayers()
{
if (!GameManager.HasInstance || GameManager.Instance.AllPlayers == null)
{
return 0;
}
int num = 0;
PlayerController[] allPlayers = GameManager.Instance.AllPlayers;
foreach (PlayerController val in allPlayers)
{
if (!((Object)(object)val == (Object)null))
{
val.ClearAllInputOverrides();
val.CurrentInputState = (PlayerInputState)0;
val.ReinitializeMovementRestrictors();
val.ToggleGunRenderers(true, string.Empty);
val.ToggleHandRenderers(true, string.Empty);
SetPrivateField(val, "m_handlingQueuedAnimation", false);
if ((Object)(object)((GameActor)val).CurrentGun != (Object)null)
{
((GameActor)val).CurrentGun.CeaseAttack(false, (ProjectileData)null);
}
if ((Object)(object)((BraveBehaviour)val).healthHaver != (Object)null)
{
((BraveBehaviour)val).healthHaver.IsVulnerable = true;
}
if ((Object)(object)((BraveBehaviour)val).gameActor != (Object)null)
{
((BraveBehaviour)val).gameActor.SuppressEffectUpdates = false;
val.IsOnFire = false;
val.CurrentFireMeterValue = 0f;
val.CurrentPoisonMeterValue = 0f;
}
num++;
}
}
return num;
}
private static int RecoverLeekItems()
{
if (!GameManager.HasInstance || GameManager.Instance.AllPlayers == null)
{
return 0;
}
int num = 0;
PlayerController[] allPlayers = GameManager.Instance.AllPlayers;
foreach (PlayerController val in allPlayers)
{
if ((Object)(object)val == (Object)null || val.activeItems == null)
{
continue;
}
for (int j = 0; j < val.activeItems.Count; j++)
{
PlayerItem item = val.activeItems[j];
if (IsMikuLeek(item))
{
RecoverLeekItem(item, val);
num++;
}
}
}
return num;
}
private static bool IsMikuLeek(PlayerItem item)
{
if ((Object)(object)item == (Object)null)
{
return false;
}
Type type = ((object)item).GetType();
if (!(type.FullName == "MikuMikuMod.Leek"))
{
return type.Name == "Leek";
}
return true;
}
private static void RecoverLeekItem(PlayerItem item, PlayerController owner)
{
if ((Object)(object)item == (Object)null)
{
return;
}
try
{
item.LastOwner = owner;
((PickupObject)item).CanBeDropped = false;
item.ClearCooldowns();
item.ResetSprite();
SetPlayerItemActive(item, active: false);
SetPrivateField(item, "m_activeElapsed", 0f);
SetPrivateField(item, "m_activeDuration", 0f);
SetPrivateField(item, "m_isDestroyed", false);
if ((Object)(object)owner != (Object)null)
{
owner.ClearInputOverride("Leeking");
owner.ToggleGunRenderers(true, "Leeking");
owner.ToggleHandRenderers(true, "Leeking");
owner.ToggleGunRenderers(true, string.Empty);
owner.ToggleHandRenderers(true, string.Empty);
SetPrivateField(owner, "m_handlingQueuedAnimation", false);
if ((Object)(object)GameUIRoot.Instance != (Object)null)
{
GameUIRoot.Instance.UpdateItemData(owner, owner.CurrentItem, owner.activeItems);
}
}
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to recover Miku Leek item: " + ex.Message));
}
}
private static void SetPlayerItemActive(PlayerItem item, bool active)
{
MethodInfo methodInfo = AccessTools.PropertySetter(typeof(PlayerItem), "IsCurrentlyActive");
if ((object)methodInfo != null)
{
methodInfo.Invoke(item, new object[1] { active });
}
else
{
SetPrivateField(item, "m_isCurrentlyActive", active);
}
}
private static void ResetCamera()
{
if (GameManager.HasInstance && !((Object)(object)GameManager.Instance.MainCameraController == (Object)null))
{
CameraController mainCameraController = GameManager.Instance.MainCameraController;
mainCameraController.StartTrackingPlayer();
mainCameraController.SetManualControl(false, false);
mainCameraController.PreventAimLook = false;
mainCameraController.LockX = false;
mainCameraController.LockY = false;
mainCameraController.LockToRoom = false;
mainCameraController.OverrideZoomScale = 1f;
mainCameraController.OverrideRecoverySpeed = -1f;
ClearCameraFocusObjects(mainCameraController);
}
}
private static void ResetUI()
{
GameUIRoot instance = GameUIRoot.Instance;
if (!((Object)(object)instance == (Object)null))
{
for (int i = 0; i < UiReasons.Length; i++)
{
string text = UiReasons[i];
instance.ShowCoreUI(text);
instance.ToggleLowerPanels(true, false, text);
instance.ToggleAllDefaultLabels(true, text);
}
ClearOverridableBool(instance, "CoreUIHidden");
ClearOverridableBool(instance, "ForceLowerPanelsInvisibleOverride");
ClearOverridableBool(instance, "m_defaultLabelsHidden");
RefreshCoreUITransition(instance);
ClearReloadBarInvisibility(instance);
instance.ToggleLowerPanels(true, false, "unstuck");
instance.ToggleAllDefaultLabels(true, "unstuck");
instance.ToggleItemPanels(true);
instance.HidePauseMenu();
instance.EndBossKillCam();
if ((Object)(object)instance.notificationController != (Object)null)
{
instance.notificationController.ForceHide();
}
}
}
private static void ResetMinimap()
{
Minimap instance = Minimap.Instance;
if (!((Object)(object)instance == (Object)null))
{
instance.TemporarilyPreventMinimap = false;
instance.HeldOpen = false;
if ((Object)(object)instance.UIMinimap != (Object)null)
{
instance.UIMinimap.ToggleState(false);
}
}
}
private static void ResetScreenFade()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
Pixelator instance = Pixelator.Instance;
if (!((Object)(object)instance == (Object)null))
{
instance.SetFadeColor(Color.clear);
instance.saturation = 1f;
}
}
private static void ResetBossHealthBars()
{
GameUIRoot instance = GameUIRoot.Instance;
if (!((Object)(object)instance == (Object)null))
{
if ((Object)(object)instance.bossController != (Object)null)
{
instance.bossController.DisableBossHealth();
}
if ((Object)(object)instance.bossController2 != (Object)null)
{
instance.bossController2.DisableBossHealth();
}
if ((Object)(object)instance.bossControllerSide != (Object)null)
{
instance.bossControllerSide.DisableBossHealth();
}
}
}
private static int CompleteStuckDraGunDeaths()
{
int num = 0;
DraGunController[] array = Object.FindObjectsOfType<DraGunController>();
foreach (DraGunController val in array)
{
if ((Object)(object)val == (Object)null || (Object)(object)((BraveBehaviour)val).healthHaver == (Object)null || !((BraveBehaviour)val).healthHaver.IsDead)
{
continue;
}
RoomHandler room = (((Object)(object)((BraveBehaviour)val).aiActor != (Object)null) ? ((BraveBehaviour)val).aiActor.ParentRoom : null);
bool flag = IsEnemyRegisteredInRoom(room, ((BraveBehaviour)val).aiActor);
try
{
val.RestrictMotion(false);
val.ModifyCamera(false);
val.BlockPitTiles(false);
val.IsTransitioning = false;
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to reset DraGun controller state: " + ex.Message));
}
CompleteDraGunRoomPlaceables(room);
if (flag)
{
try
{
((BraveBehaviour)val).healthHaver.DeathAnimationComplete((tk2dSpriteAnimator)null, (tk2dSpriteAnimationClip)null);
num++;
}
catch (Exception ex2)
{
Log.LogWarning((object)("Failed to complete DraGun death animation, deregistering enemy instead: " + ex2.Message));
TryDeregisterEnemy(room, ((BraveBehaviour)val).aiActor);
}
}
}
return num;
}
private static void CompleteDraGunRoomPlaceables(RoomHandler room)
{
if (room == null)
{
return;
}
List<DraGunRoomPlaceable> componentsAbsoluteInRoom = room.GetComponentsAbsoluteInRoom<DraGunRoomPlaceable>();
for (int i = 0; i < componentsAbsoluteInRoom.Count; i++)
{
DraGunRoomPlaceable val = componentsAbsoluteInRoom[i];
if (!((Object)(object)val == (Object)null))
{
val.DraGunKilled = true;
try
{
val.ExtendDeathBridge();
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to extend DraGun death bridge: " + ex.Message));
}
}
}
}
private static void FixCurrentRooms(RescueResult result)
{
List<RoomHandler> roomsToRescue = GetRoomsToRescue();
for (int i = 0; i < roomsToRescue.Count; i++)
{
RoomHandler val = roomsToRescue[i];
if (val == null)
{
continue;
}
bool flag = PruneDeadEnemies(val);
if (!val.HasActiveEnemies((ActiveEnemyType)1))
{
SetPrivateField(val, "numberOfTimedWavesOnDeck", 0);
val.forceTeleportersActive = true;
CompleteDraGunRoomPlaceables(val);
if (ForceUnsealRoom(val))
{
result.UnsealedRooms++;
}
if (TriggerRoomClearFlowIfNeeded(val))
{
result.TriggeredRewards++;
}
if (flag || val.IsSealed)
{
result.FixedRooms++;
}
}
}
}
private static List<RoomHandler> GetRoomsToRescue()
{
List<RoomHandler> list = new List<RoomHandler>();
if (!GameManager.HasInstance)
{
return list;
}
PlayerController[] allPlayers = GameManager.Instance.AllPlayers;
if (allPlayers != null)
{
for (int i = 0; i < allPlayers.Length; i++)
{
if ((Object)(object)allPlayers[i] != (Object)null && allPlayers[i].CurrentRoom != null && !list.Contains(allPlayers[i].CurrentRoom))
{
list.Add(allPlayers[i].CurrentRoom);
}
}
}
if ((Object)(object)GameManager.Instance.BestActivePlayer != (Object)null && GameManager.Instance.BestActivePlayer.CurrentRoom != null && !list.Contains(GameManager.Instance.BestActivePlayer.CurrentRoom))
{
list.Add(GameManager.Instance.BestActivePlayer.CurrentRoom);
}
return list;
}
private static bool PruneDeadEnemies(RoomHandler room)
{
bool result = false;
List<AIActor> activeEnemiesList = GetActiveEnemiesList(room);
if (activeEnemiesList == null)
{
return false;
}
for (int num = activeEnemiesList.Count - 1; num >= 0; num--)
{
AIActor val = activeEnemiesList[num];
if ((Object)(object)val == (Object)null)
{
activeEnemiesList.RemoveAt(num);
result = true;
}
else if ((Object)(object)((BraveBehaviour)val).healthHaver != (Object)null && ((BraveBehaviour)val).healthHaver.IsDead)
{
bool flag = false;
try
{
((BraveBehaviour)val).healthHaver.DeathAnimationComplete((tk2dSpriteAnimator)null, (tk2dSpriteAnimationClip)null);
flag = true;
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to finalize dead enemy, deregistering instead: " + ex.Message));
}
if (!flag && activeEnemiesList.Contains(val))
{
activeEnemiesList.Remove(val);
}
result = true;
}
}
return result;
}
private static bool TriggerRoomClearFlowIfNeeded(RoomHandler room)
{
if (room == null || !room.EverHadEnemies || GetPrivateBool(room, "m_hasGivenReward"))
{
return false;
}
try
{
if ((Object)(object)GameManager.Instance != (Object)null && (Object)(object)GameManager.Instance.DungeonMusicController != (Object)null)
{
GameManager.Instance.DungeonMusicController.NotifyCurrentRoomEnemiesCleared();
}
room.OnEnemiesCleared?.Invoke();
GameManager.BroadcastRoomTalkDoerFsmEvent("roomCleared");
return true;
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to trigger room clear flow: " + ex.Message));
return false;
}
}
private static bool ForceUnsealRoom(RoomHandler room)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
bool result = room.IsSealed;
try
{
room.npcSealState = (NPCSealState)0;
room.UnsealRoom();
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to unseal room through RoomHandler: " + ex.Message));
}
if (room.connectedDoors != null)
{
for (int i = 0; i < room.connectedDoors.Count; i++)
{
DungeonDoorController val = room.connectedDoors[i];
if (!((Object)(object)val == (Object)null))
{
if (val.IsSealed)
{
result = true;
}
try
{
val.KeepBossDoorSealed = false;
val.DoUnseal(room);
val.IsSealed = false;
}
catch (Exception ex2)
{
Log.LogWarning((object)("Failed to unseal door: " + ex2.Message));
}
}
}
}
if (room.standaloneBlockers != null)
{
for (int j = 0; j < room.standaloneBlockers.Count; j++)
{
DungeonDoorSubsidiaryBlocker val2 = room.standaloneBlockers[j];
if (!((Object)(object)val2 == (Object)null))
{
if (val2.isSealed)
{
result = true;
}
try
{
val2.Unseal();
}
catch (Exception ex3)
{
Log.LogWarning((object)("Failed to unseal standalone blocker: " + ex3.Message));
}
}
}
}
return result;
}
private static int IgnoreRoomClearEnemies(RoomHandler room)
{
int num = 0;
List<AIActor> activeEnemiesList = GetActiveEnemiesList(room);
if (activeEnemiesList == null)
{
return 0;
}
for (int i = 0; i < activeEnemiesList.Count; i++)
{
AIActor val = activeEnemiesList[i];
if ((Object)(object)val != (Object)null && !val.IgnoreForRoomClear)
{
val.IgnoreForRoomClear = true;
num++;
}
}
return num;
}
private static int ForceOpenRoom(RoomHandler room, OpenRoomResult result)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Invalid comparison between Unknown and I4
int num = 0;
SetPrivateField(room, "numberOfTimedWavesOnDeck", 0);
room.CompletelyPreventLeaving = false;
room.PreventMinimapUpdates = false;
room.forceTeleportersActive = true;
room.npcSealState = (NPCSealState)0;
try
{
room.UnsealRoom();
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to unseal room in openroom: " + ex.Message));
}
if (room.connectedDoors != null)
{
for (int i = 0; i < room.connectedDoors.Count; i++)
{
DungeonDoorController val = room.connectedDoors[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
bool isSealed = val.IsSealed;
bool isLocked = val.isLocked;
bool isOpen = val.IsOpen;
try
{
val.KeepBossDoorSealed = false;
val.DoUnseal(room);
val.IsSealed = false;
if (val.isLocked)
{
val.Unlock();
}
if ((int)val.Mode == 0 || (int)val.Mode == 2)
{
val.Open(false);
}
}
catch (Exception ex2)
{
Log.LogWarning((object)("Failed to force-open door: " + ex2.Message));
}
if (isSealed)
{
result.DoorsUnsealed++;
}
if (isLocked)
{
result.DoorsUnlocked++;
}
if (!isOpen && val.IsOpen)
{
result.DoorsOpened++;
}
}
}
if (room.standaloneBlockers != null)
{
for (int j = 0; j < room.standaloneBlockers.Count; j++)
{
DungeonDoorSubsidiaryBlocker val2 = room.standaloneBlockers[j];
if (!((Object)(object)val2 == (Object)null))
{
bool isSealed2 = val2.isSealed;
try
{
val2.Unseal();
}
catch (Exception ex3)
{
Log.LogWarning((object)("Failed to unseal standalone blocker in openroom: " + ex3.Message));
}
if (isSealed2)
{
num++;
}
}
}
}
return num;
}
private static int RestoreRoomTeleporters(RoomHandler room)
{
int num = 0;
room.forceTeleportersActive = true;
List<TeleporterController> componentsAbsoluteInRoom = room.GetComponentsAbsoluteInRoom<TeleporterController>();
for (int i = 0; i < componentsAbsoluteInRoom.Count; i++)
{
TeleporterController val = componentsAbsoluteInRoom[i];
if (!((Object)(object)val == (Object)null))
{
SetPrivateField(val, "m_activated", true);
if ((Object)(object)val.extantActiveVFX != (Object)null)
{
val.extantActiveVFX.SetActive(true);
}
if ((Object)(object)val.portalVFX != (Object)null)
{
((Component)val.portalVFX).gameObject.SetActive(true);
}
num++;
}
}
Minimap instance = Minimap.Instance;
if ((Object)(object)instance != (Object)null)
{
instance.PreventAllTeleports = false;
if (instance.RoomToTeleportMap != null && instance.RoomToTeleportMap.ContainsKey(room))
{
GameObject val2 = instance.RoomToTeleportMap[room];
if ((Object)(object)val2 != (Object)null)
{
val2.SetActive(true);
}
UpdateMinimapTeleporterIcon(instance, room);
}
}
return num;
}
private static bool RestoreMinimapRoom(RoomHandler room)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Invalid comparison between Unknown and I4
if (room == null)
{
return false;
}
room.PreventMinimapUpdates = false;
room.RevealedOnMap = true;
if ((int)room.visibility == 0 || (int)room.visibility == 3)
{
room.visibility = (VisibilityStatus)2;
}
Minimap instance = Minimap.Instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
instance.TemporarilyPreventMinimap = false;
instance.PreventAllTeleports = false;
instance.HeldOpen = false;
instance.RevealMinimapRoom(room, true, true, true);
UpdateMinimapTeleporterIcon(instance, room);
return true;
}
private static void UpdateMinimapTeleporterIcon(Minimap minimap, RoomHandler room)
{
AccessTools.Method(typeof(Minimap), "UpdateTeleporterIconForRoom", (Type[])null, (Type[])null)?.Invoke(minimap, new object[1] { room });
}
private static bool IsEnemyRegisteredInRoom(RoomHandler room, AIActor enemy)
{
if (room == null || (Object)(object)enemy == (Object)null)
{
return false;
}
return GetActiveEnemiesList(room)?.Contains(enemy) ?? false;
}
private static void TryDeregisterEnemy(RoomHandler room, AIActor enemy)
{
if (room == null || (Object)(object)enemy == (Object)null)
{
return;
}
try
{
room.DeregisterEnemy(enemy, false);
}
catch (Exception ex)
{
Log.LogWarning((object)("Failed to deregister enemy: " + ex.Message));
}
}
private static List<AIActor> GetActiveEnemiesList(RoomHandler room)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(RoomHandler), "activeEnemies");
if ((object)fieldInfo != null)
{
return fieldInfo.GetValue(room) as List<AIActor>;
}
return null;
}
private static void ClearOverridableBool(object target, string fieldName)
{
FieldInfo fieldInfo = AccessTools.Field(target.GetType(), fieldName);
if ((object)fieldInfo != null)
{
object? value = fieldInfo.GetValue(target);
OverridableBool val = (OverridableBool)((value is OverridableBool) ? value : null);
if (val != null)
{
val.ClearOverrides();
}
}
}
private static void RefreshCoreUITransition(GameUIRoot ui)
{
MethodInfo methodInfo = AccessTools.Method(typeof(GameUIRoot), "RecalculateTargetPositions", (Type[])null, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(typeof(GameUIRoot), "CoreUITransition", (Type[])null, (Type[])null);
methodInfo?.Invoke(ui, null);
if ((object)methodInfo2 != null && methodInfo2.Invoke(ui, null) is IEnumerator enumerator)
{
((MonoBehaviour)ui).StartCoroutine(enumerator);
}
}
private static void ClearReloadBarInvisibility(GameUIRoot ui)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(GameUIRoot), "m_extantReloadBars");
if ((object)fieldInfo == null || !(fieldInfo.GetValue(ui) is List<GameUIReloadBarController> list))
{
return;
}
for (int i = 0; i < list.Count; i++)
{
if ((Object)(object)list[i] != (Object)null)
{
list[i].SetInvisibility(false, "CoreUI");
}
}
}
private static void ClearCameraFocusObjects(CameraController camera)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(CameraController), "m_focusObjects");
if ((object)fieldInfo != null && fieldInfo.GetValue(camera) is IList list)
{
list.Clear();
}
}
private static bool GetPrivateBool(object target, string fieldName)
{
FieldInfo fieldInfo = AccessTools.Field(target.GetType(), fieldName);
if ((object)fieldInfo != null && fieldInfo.GetValue(target) is bool)
{
return (bool)fieldInfo.GetValue(target);
}
return false;
}
private static void SetPrivateField(object target, string fieldName, object value)
{
AccessTools.Field(target.GetType(), fieldName)?.SetValue(target, value);
}
}