Decompiled source of Final Judge v1.0.1

FinalJudge.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using HutongGames.PlayMaker;
using HutongGames.PlayMaker.Actions;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Final Judge")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Final Judge")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("554080D8-4C10-49A2-BBDF-DB2662497225")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("name.ryanblocker.finaljudge", "Final Judge", "1.0.0")]
public sealed class FinalJudge : BaseUnityPlugin
{
	private const string ArenaSceneName = "Coral_Judge_Arena";

	private const string BossObjectName = "Last Judge";

	private const string BossControlFsmName = "Control";

	private const string FlamedUpVariableName = "Flamed Up";

	private const string DockPrefabBundleSearchName = "localpoolprefabs_assets_areadocks";

	private static readonly string[] LavaRockDependencyBundleNames = new string[4] { "tk2dcollections_assets_areadocks.bundle", "tk2danimations_assets_areadocks.bundle", "textures_assets_areadocks.bundle", "materials_assets_areadocks.bundle" };

	private const string LavaRockAssetPath = "Assets/Prefabs/Enemies/Projectiles/DF Lava Rock.prefab";

	private const string BombRockAssetPath = "Assets/Prefabs/Enemies/Projectiles/DF Bomb Rock.prefab";

	private const string NativeFlameWavePrefabName = "Last Judge Flame Wave";

	private const string NativeStompWavePrefabName = "Last Judge Stomp Wave";

	private const string NativeChargePillarPrefabName = "Last Judge Charge Bomb";

	private const string NativeBossHeader = "The";

	private const string NativeBossTitle = "Last Judge";

	private const string FinalBossHeader = "Harbinger of Sin";

	private const string FinalBossTitle = "Final Judge";

	private const int FinalBossHealth = 1500;

	private const int FinalPhaseHealth = 600;

	private const int SpinLavaRockCount = 6;

	private const float SpinLavaRockSpeed = 30f;

	private const float SpinLavaRockSpawnRadius = 1.5f;

	private const float LavaRockInterval = 0.18f;

	private const float CenserShockwaveDelay = 0.5f;

	private const float CenserParticleWaveSpeed = 180f;

	private const float SlamPillarInterval = 0.1f;

	private const float DefaultChargePillarWidth = 4.1f;

	private const float SlamPillarSpacing = 3.8f;

	private const float NativeChargeSpeed = 40f;

	private const float ChargePillarInterval = 0.095f;

	private const float NativeChargeDuration = 0.45f;

	private const float ExtendedChargeDuration = 1.5f;

	private const float PostFinalPhaseRoarChargeDuration = 4f;

	private const float BombSpiralChance = 0.5f;

	private const float BombSpiralDuration = 3.5f;

	private const float BombRockInterval = 0.3f;

	private const float BombRockDownwardExclusionAngle = 35f;

	private static bool inJudgeFight;

	private static bool replaceBossTitleLocalization;

	private static bool healthSetupRunning;

	private static bool healthConfigured;

	private static bool fieryPhaseConfigured;

	private static bool lavaBurstSpawnedThisSpin;

	private static bool lavaRockPoolConfigured;

	private static bool throwImpactHandled;

	private static bool suppressNativeStompWaves;

	private static bool slamPillarWaveStarted;

	private static bool nativeStompAnticRemoved;

	private static bool chargePillarTrailConfigured;

	private static bool rageAt1100Triggered;

	private static bool rageAt400Triggered;

	private static bool rageTransitionScheduled;

	private static bool restoreRageRoarTransitionOnCharge;

	private static bool extendedChargeRunning;

	private static bool noStaggersConfigured;

	private static bool staggerIndicatorSuppressionRunning;

	private static bool staggerEscapeScheduled;

	private static bool bombSpiralActive;

	private static bool bombSpiralStarted;

	private static bool finalPhaseRoarCompleted;

	private static bool postFinalPhaseRoarChargePending;

	private static float activeExtendedChargeDuration = 1.5f;

	private static float judgeGravityScale = 1f;

	private static bool chargeDamageMaintenanceRunning;

	private static bool finalPhaseContactMaintenanceRunning;

	private static PlayMakerFSM bossControlFsm;

	private static HealthManager judgeHealthManager;

	private static GameObject lavaRockPrefab;

	private static GameObject bombRockPrefab;

	private static GameObject stompWavePrefab;

	private static GameObject chargePillarPrefab;

	private static float chargePillarWidth = 4.1f;

	private static readonly GameObject[] stompParticleTemplates = (GameObject[])(object)new GameObject[2];

	private static readonly HashSet<int> doubledLavaRockDamagers = new HashSet<int>();

	private static readonly List<DamageHero> baselineContactDamagers = new List<DamageHero>();

	private static readonly FieldInfo DamageDealtField = typeof(DamageHero).GetField("damageDealt", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

	private static float stompWaveSpeed = 12f;

	private static AsyncOperationHandle<IAssetBundleResource> dockBundleHandle;

	private static bool dockBundleHandleValid;

	private static readonly List<AsyncOperationHandle<IAssetBundleResource>> lavaRockDependencyHandles = new List<AsyncOperationHandle<IAssetBundleResource>>();

	private static bool warnedMissingLavaRock;

	public static FinalJudge Instance { get; private set; }

	public ManualLogSource Log => ((BaseUnityPlugin)this).Logger;

	private void Awake()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Harmony.CreateAndPatchAll(typeof(FinalJudge), (string)null);
		SceneManager.sceneLoaded += OnSceneLoaded;
		OnSceneLoaded(SceneManager.GetActiveScene(), (LoadSceneMode)0);
		((MonoBehaviour)this).StartCoroutine(LoadLavaRockPrefab());
		Log.LogInfo((object)"Final Judge loaded and initialized.");
	}

	private void OnDestroy()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		SceneManager.sceneLoaded -= OnSceneLoaded;
		if (dockBundleHandleValid)
		{
			Addressables.Release<IAssetBundleResource>(dockBundleHandle);
			dockBundleHandleValid = false;
		}
		foreach (AsyncOperationHandle<IAssetBundleResource> lavaRockDependencyHandle in lavaRockDependencyHandles)
		{
			Addressables.Release<IAssetBundleResource>(lavaRockDependencyHandle);
		}
		lavaRockDependencyHandles.Clear();
	}

	private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		inJudgeFight = ((Scene)(ref scene)).name == "Coral_Judge_Arena";
		replaceBossTitleLocalization = false;
		healthSetupRunning = false;
		healthConfigured = false;
		fieryPhaseConfigured = false;
		lavaBurstSpawnedThisSpin = false;
		lavaRockPoolConfigured = false;
		throwImpactHandled = false;
		suppressNativeStompWaves = false;
		slamPillarWaveStarted = false;
		nativeStompAnticRemoved = false;
		chargePillarTrailConfigured = false;
		rageAt1100Triggered = false;
		rageAt400Triggered = false;
		rageTransitionScheduled = false;
		restoreRageRoarTransitionOnCharge = false;
		extendedChargeRunning = false;
		noStaggersConfigured = false;
		staggerIndicatorSuppressionRunning = false;
		staggerEscapeScheduled = false;
		bombSpiralActive = false;
		bombSpiralStarted = false;
		finalPhaseRoarCompleted = false;
		postFinalPhaseRoarChargePending = false;
		activeExtendedChargeDuration = 1.5f;
		judgeGravityScale = 1f;
		chargeDamageMaintenanceRunning = false;
		finalPhaseContactMaintenanceRunning = false;
		bossControlFsm = null;
		judgeHealthManager = null;
		stompWavePrefab = null;
		chargePillarPrefab = null;
		chargePillarWidth = 4.1f;
		stompParticleTemplates[0] = null;
		stompParticleTemplates[1] = null;
		doubledLavaRockDamagers.Clear();
		baselineContactDamagers.Clear();
		if (inJudgeFight)
		{
			Instance.Log.LogInfo((object)"Final Judge: Last Judge arena loaded.");
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(FsmState), "OnEnter")]
	private static bool PreventJudgeStaggerStateActions(FsmState __instance)
	{
		object obj;
		if (__instance == null)
		{
			obj = null;
		}
		else
		{
			Fsm fsm = __instance.Fsm;
			obj = ((fsm != null) ? fsm.FsmComponent : null);
		}
		PlayMakerFSM val = (PlayMakerFSM)obj;
		if (!inJudgeFight || (Object)(object)val == (Object)null || val.FsmName != "Control" || !IsJudgeHierarchy(((Component)val).transform))
		{
			return true;
		}
		return __instance.Name.IndexOf("Stun", StringComparison.OrdinalIgnoreCase) < 0 && __instance.Name.IndexOf("Stagger", StringComparison.OrdinalIgnoreCase) < 0;
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(FsmState), "OnEnter")]
	private static void PrepareChargeState(FsmState __instance)
	{
		object obj;
		if (__instance == null)
		{
			obj = null;
		}
		else
		{
			Fsm fsm = __instance.Fsm;
			obj = ((fsm != null) ? fsm.FsmComponent : null);
		}
		PlayMakerFSM val = (PlayMakerFSM)obj;
		if (!inJudgeFight || (Object)(object)val == (Object)null || val.FsmName != "Control" || !IsJudgeHierarchy(((Component)val).transform) || __instance.Name != "Charge")
		{
			return;
		}
		bool flag = postFinalPhaseRoarChargePending || (finalPhaseRoarCompleted && (Object)(object)judgeHealthManager != (Object)null && judgeHealthManager.hp <= 600);
		activeExtendedChargeDuration = ((flag && postFinalPhaseRoarChargePending) ? 4f : 1.5f);
		if (flag)
		{
			postFinalPhaseRoarChargePending = false;
		}
		FsmStateAction[] actions = __instance.Actions;
		foreach (FsmStateAction val2 in actions)
		{
			if (((object)val2).GetType().Name == "Wait")
			{
				SetFsmFloatField(val2, "time", flag ? activeExtendedChargeDuration : 0.45f);
			}
			else if (((object)val2).GetType().Name == "RayCast2dV2")
			{
				val2.Enabled = !flag;
			}
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(FsmState), "OnEnter")]
	private static void PrepareFinalPhaseStompAntic(FsmState __instance)
	{
		object obj;
		if (__instance == null)
		{
			obj = null;
		}
		else
		{
			Fsm fsm = __instance.Fsm;
			obj = ((fsm != null) ? fsm.FsmComponent : null);
		}
		PlayMakerFSM val = (PlayMakerFSM)obj;
		if (!inJudgeFight || (Object)(object)val == (Object)null || val.FsmName != "Control" || !IsJudgeHierarchy(((Component)val).transform) || __instance.Name != "Stomp Flame Antic")
		{
			return;
		}
		bool enabled = (Object)(object)judgeHealthManager != (Object)null && judgeHealthManager.hp < 600;
		FsmStateAction[] actions = __instance.Actions;
		foreach (FsmStateAction val2 in actions)
		{
			if (((object)val2).GetType().Name != "Wait")
			{
				val2.Enabled = enabled;
			}
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(FsmState), "OnEnter")]
	private static bool BeginBombSpiralInstead(FsmState __instance)
	{
		object obj;
		if (__instance == null)
		{
			obj = null;
		}
		else
		{
			Fsm fsm = __instance.Fsm;
			obj = ((fsm != null) ? fsm.FsmComponent : null);
		}
		PlayMakerFSM val = (PlayMakerFSM)obj;
		if (!inJudgeFight || (Object)(object)val == (Object)null || val.FsmName != "Control" || !IsJudgeHierarchy(((Component)val).transform) || __instance.Name != "Spin Antic" || bombSpiralActive || (Object)(object)judgeHealthManager == (Object)null || judgeHealthManager.hp >= 600 || Random.value > 0.5f)
		{
			return true;
		}
		bombSpiralActive = true;
		bombSpiralStarted = false;
		Instance.Log.LogInfo((object)"Final Judge: converted the current spiral into a bomb-rock spiral.");
		return true;
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(FsmState), "OnEnter")]
	private static void OnFsmStateEntered(FsmState __instance)
	{
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		object obj;
		if (__instance == null)
		{
			obj = null;
		}
		else
		{
			Fsm fsm = __instance.Fsm;
			obj = ((fsm != null) ? fsm.FsmComponent : null);
		}
		PlayMakerFSM val = (PlayMakerFSM)obj;
		if (!inJudgeFight || (Object)(object)val == (Object)null || val.FsmName != "Control" || !IsJudgeHierarchy(((Component)val).transform))
		{
			return;
		}
		bossControlFsm = val;
		Rigidbody2D component = ((Component)val).GetComponent<Rigidbody2D>();
		if ((Object)(object)component != (Object)null && component.gravityScale > 0f)
		{
			judgeGravityScale = component.gravityScale;
		}
		CacheStompParticleTemplates(val);
		CacheChargePillarPrefab(val);
		ConfigureChargePillarTrail(val);
		ConfigureNoStaggers(val);
		RemoveNativeStompAntic(val);
		ConfigureFieryPhase(val);
		if (__instance.Name == "Idle" && (Object)(object)judgeHealthManager != (Object)null && judgeHealthManager.hp > 1100)
		{
			CacheBaselineContactDamagers(((Component)val).transform);
		}
		if (__instance.Name == "Stomp JumpAntic")
		{
			slamPillarWaveStarted = false;
			suppressNativeStompWaves = (Object)(object)judgeHealthManager == (Object)null || judgeHealthManager.hp >= 600;
		}
		else if (__instance.Name == "Stomp Land" && !slamPillarWaveStarted)
		{
			slamPillarWaveStarted = true;
			Vector3 origin = FindNamedChildPosition(((Component)val).transform, "Stomp Flame Point");
			((MonoBehaviour)Instance).StartCoroutine(SpawnSlamPillarWaves(origin));
		}
		else if (__instance.Name == "Stomp Flame Antic")
		{
			suppressNativeStompWaves = (Object)(object)judgeHealthManager == (Object)null || judgeHealthManager.hp >= 600;
		}
		else if (__instance.Name == "Stomp Recover" || __instance.Name == "Idle")
		{
			suppressNativeStompWaves = false;
		}
		if (__instance.Name == "Throw Antic")
		{
			throwImpactHandled = false;
		}
		else if (__instance.Name == "Censer Slam" && !throwImpactHandled)
		{
			throwImpactHandled = true;
			Vector3 impactPosition = FindCenserImpactPosition(((Component)val).transform);
			SpawnCenserImpactAttack(impactPosition);
		}
		if (__instance.Name == "Spin Antic")
		{
			lavaBurstSpawnedThisSpin = false;
			if (!bombSpiralActive && (Object)(object)judgeHealthManager != (Object)null && judgeHealthManager.hp < 1100)
			{
				ArmNativeFourWaveSpin(val);
			}
		}
		else if (__instance.Name == "Flame Dir")
		{
			lavaBurstSpawnedThisSpin = false;
		}
		else if (__instance.Name == "Charge")
		{
			if (!chargeDamageMaintenanceRunning)
			{
				chargeDamageMaintenanceRunning = true;
				((MonoBehaviour)Instance).StartCoroutine(MaintainChargeContactDamage(val));
			}
			if ((activeExtendedChargeDuration == 4f || (finalPhaseRoarCompleted && (Object)(object)judgeHealthManager != (Object)null && judgeHealthManager.hp <= 600)) && !extendedChargeRunning)
			{
				extendedChargeRunning = true;
				((MonoBehaviour)Instance).StartCoroutine(ControlExtendedCharge(val, activeExtendedChargeDuration));
			}
		}
		else if (__instance.Name == "Charge Antic 1" && restoreRageRoarTransitionOnCharge)
		{
			finalPhaseRoarCompleted = true;
			if (!finalPhaseContactMaintenanceRunning)
			{
				finalPhaseContactMaintenanceRunning = true;
				((MonoBehaviour)Instance).StartCoroutine(MaintainFinalPhaseContactDamage(val));
			}
			RestoreRageRoarTransition(val);
		}
		if (__instance.Name == "Rage Check")
		{
			ScheduleThresholdRageIfNeeded(val);
		}
		if (bombSpiralActive && (__instance.Name == "Idle" || __instance.Name == "Throw Antic" || __instance.Name == "Stomp JumpAntic" || __instance.Name == "Charge Antic 1"))
		{
			bombSpiralActive = false;
			bombSpiralStarted = false;
			Instance.Log.LogInfo((object)"Final Judge: bomb-rock spiral finished and normal projectiles were restored.");
		}
		if ((__instance.Name.IndexOf("Stun", StringComparison.OrdinalIgnoreCase) >= 0 || __instance.Name.IndexOf("Stagger", StringComparison.OrdinalIgnoreCase) >= 0) && !staggerEscapeScheduled)
		{
			staggerEscapeScheduled = true;
			((MonoBehaviour)Instance).StartCoroutine(EscapeStaggerState(val));
		}
		if (!healthSetupRunning && !healthConfigured)
		{
			healthSetupRunning = true;
			((MonoBehaviour)Instance).StartCoroutine(FindAndSetJudgeHealth());
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(FSMActivator), "ActivateStaggered")]
	private static bool SuppressJudgeStaggerIndicator(FSMActivator __instance)
	{
		return !inJudgeFight || (Object)(object)__instance == (Object)null || !IsJudgeHierarchy(((Component)__instance).transform);
	}

	private static IEnumerator LoadLavaRockPrefab()
	{
		yield return Addressables.InitializeAsync(true);
		IResourceLocation dockBundleLocation = null;
		List<IResourceLocation> dependencyLocations = new List<IResourceLocation>();
		HashSet<string> dependencyIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		IList<IResourceLocation> locations = default(IList<IResourceLocation>);
		foreach (IResourceLocator locator in Addressables.ResourceLocators)
		{
			foreach (object key in locator.Keys)
			{
				if (!locator.Locate(key, (Type)null, ref locations) || locations == null)
				{
					continue;
				}
				foreach (IResourceLocation location in locations)
				{
					if (location.ResourceType == typeof(IAssetBundleResource) && !string.IsNullOrEmpty(location.InternalId))
					{
						string[] lavaRockDependencyBundleNames = LavaRockDependencyBundleNames;
						foreach (string dependencyName in lavaRockDependencyBundleNames)
						{
							if (location.InternalId.EndsWith(dependencyName, StringComparison.OrdinalIgnoreCase) && dependencyIds.Add(location.InternalId))
							{
								dependencyLocations.Add(location);
								break;
							}
						}
						if (location.InternalId.IndexOf("areadocks", StringComparison.OrdinalIgnoreCase) >= 0 && (location.InternalId.IndexOf("textures_assets_", StringComparison.OrdinalIgnoreCase) >= 0 || location.InternalId.IndexOf("materials_assets_", StringComparison.OrdinalIgnoreCase) >= 0) && dependencyIds.Add(location.InternalId))
						{
							dependencyLocations.Add(location);
						}
					}
					if (location.ResourceType == typeof(IAssetBundleResource) && !string.IsNullOrEmpty(location.InternalId) && location.InternalId.IndexOf("localpoolprefabs_assets_areadocks", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						dockBundleLocation = location;
						break;
					}
				}
				locations = null;
			}
		}
		if (dockBundleLocation == null)
		{
			Instance.Log.LogError((object)"Final Judge [LAVA ROCK]: Deep Docks prefab bundle location was not found.");
			yield break;
		}
		foreach (IResourceLocation dependencyLocation in dependencyLocations)
		{
			AsyncOperationHandle<IAssetBundleResource> dependencyHandle = Addressables.LoadAssetAsync<IAssetBundleResource>(dependencyLocation);
			lavaRockDependencyHandles.Add(dependencyHandle);
			yield return dependencyHandle;
			if ((int)dependencyHandle.Status != 1)
			{
				Instance.Log.LogError((object)("Final Judge [LAVA ROCK]: failed to load dependency bundle " + dependencyLocation.InternalId));
				yield break;
			}
		}
		Instance.Log.LogInfo((object)("Final Judge: loaded " + dependencyLocations.Count + " Deep Docks tk2d rendering dependency bundles."));
		dockBundleHandle = Addressables.LoadAssetAsync<IAssetBundleResource>(dockBundleLocation);
		dockBundleHandleValid = true;
		yield return dockBundleHandle;
		if ((int)dockBundleHandle.Status != 1 || dockBundleHandle.Result == null)
		{
			Instance.Log.LogError((object)"Final Judge [LAVA ROCK]: Addressables failed to load the Deep Docks prefab bundle.");
			yield break;
		}
		AssetBundle bundle = dockBundleHandle.Result.GetAssetBundle();
		if ((Object)(object)bundle == (Object)null)
		{
			Instance.Log.LogError((object)"Final Judge [LAVA ROCK]: managed Deep Docks prefab bundle was null.");
			yield break;
		}
		AssetBundleRequest lavaRockRequest = bundle.LoadAssetAsync<GameObject>("Assets/Prefabs/Enemies/Projectiles/DF Lava Rock.prefab");
		yield return lavaRockRequest;
		Object asset = lavaRockRequest.asset;
		lavaRockPrefab = (GameObject)(object)((asset is GameObject) ? asset : null);
		if ((Object)(object)lavaRockPrefab == (Object)null)
		{
			Instance.Log.LogError((object)"Final Judge [LAVA ROCK]: failed to deserialize DF Lava Rock after its dependencies.");
			yield break;
		}
		AssetBundleRequest bombRockRequest = bundle.LoadAssetAsync<GameObject>("Assets/Prefabs/Enemies/Projectiles/DF Bomb Rock.prefab");
		yield return bombRockRequest;
		Object asset2 = bombRockRequest.asset;
		bombRockPrefab = (GameObject)(object)((asset2 is GameObject) ? asset2 : null);
		if ((Object)(object)bombRockPrefab == (Object)null)
		{
			AssetBundleRequest allGameObjectsRequest = bundle.LoadAllAssetsAsync<GameObject>();
			yield return allGameObjectsRequest;
			Object[] allAssets = allGameObjectsRequest.allAssets;
			foreach (Object asset3 in allAssets)
			{
				GameObject candidate = (GameObject)(object)((asset3 is GameObject) ? asset3 : null);
				if ((Object)(object)candidate != (Object)null && ((Object)candidate).name == "DF Bomb Rock")
				{
					bombRockPrefab = candidate;
					break;
				}
			}
		}
		if ((Object)(object)bombRockPrefab == (Object)null)
		{
			Instance.Log.LogError((object)"Final Judge [BOMB ROCK]: DF Bomb Rock was not found in the managed bundle.");
		}
		else
		{
			Instance.Log.LogInfo((object)"Final Judge: loaded DF Lava Rock and DF Bomb Rock through the game-managed Addressables bundle.");
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(ObjectPool), "Spawn", new Type[]
	{
		typeof(GameObject),
		typeof(Transform),
		typeof(Vector3),
		typeof(Quaternion),
		typeof(bool)
	})]
	private static void HandleJudgePooledPrefab(GameObject prefab, GameObject __result)
	{
		//IL_0054: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		if (!inJudgeFight || (Object)(object)prefab == (Object)null)
		{
			return;
		}
		if (((Object)prefab).name == "Last Judge Stomp Wave")
		{
			stompWavePrefab = prefab;
			Rigidbody2D val = (((Object)(object)__result != (Object)null) ? __result.GetComponent<Rigidbody2D>() : null);
			if ((Object)(object)val != (Object)null && Mathf.Abs(val.linearVelocity.x) > 0.1f)
			{
				stompWaveSpeed = Mathf.Abs(val.linearVelocity.x);
			}
		}
		else if (((Object)prefab).name == "Last Judge Charge Bomb")
		{
			chargePillarPrefab = prefab;
			Renderer val2 = (((Object)(object)__result != (Object)null) ? __result.GetComponentInChildren<Renderer>(true) : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Bounds bounds = val2.bounds;
				if (((Bounds)(ref bounds)).size.x > 0.1f)
				{
					bounds = val2.bounds;
					chargePillarWidth = ((Bounds)(ref bounds)).size.x;
				}
			}
		}
		if (bombSpiralActive && ((Object)prefab).name == "Last Judge Flame Wave")
		{
			if ((Object)(object)__result != (Object)null)
			{
				__result.SetActive(false);
			}
			if (!bombSpiralStarted && (Object)(object)bossControlFsm != (Object)null)
			{
				bombSpiralStarted = true;
				((MonoBehaviour)Instance).StartCoroutine(RunBombSpiralWindow(bossControlFsm));
			}
		}
		else if (!bombSpiralActive && !lavaBurstSpawnedThisSpin && !(((Object)prefab).name != "Last Judge Flame Wave") && !((Object)(object)bossControlFsm == (Object)null))
		{
			lavaBurstSpawnedThisSpin = true;
			((MonoBehaviour)Instance).StartCoroutine(SpawnSpinLavaRocks(((Component)bossControlFsm).transform.position));
			Instance.Log.LogInfo((object)"Final Judge: first flame wave released; starting lava-rock sequence.");
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(ObjectPool), "Spawn", new Type[]
	{
		typeof(GameObject),
		typeof(Transform),
		typeof(Vector3),
		typeof(Quaternion),
		typeof(bool)
	})]
	private static bool SuppressOriginalSlamFireWaves(GameObject prefab, Vector3 __2, ref GameObject __result)
	{
		if (inJudgeFight && suppressNativeStompWaves && (Object)(object)prefab != (Object)null && ((Object)prefab).name == "Last Judge Stomp Wave")
		{
			__result = null;
			return false;
		}
		return true;
	}

	private static Vector3 FindNamedChildPosition(Transform root, string childName)
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0043: Unknown result type (might be due to invalid IL or missing references)
		Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == childName)
			{
				return val.position;
			}
		}
		return root.position;
	}

	private static IEnumerator SpawnSlamPillarWaves(Vector3 origin)
	{
		//IL_0007: 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)
		if ((Object)(object)chargePillarPrefab == (Object)null)
		{
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject candidate in array)
			{
				if (((Object)candidate).name == "Last Judge Charge Bomb")
				{
					chargePillarPrefab = candidate;
					break;
				}
			}
		}
		if ((Object)(object)chargePillarPrefab == (Object)null)
		{
			Instance.Log.LogWarning((object)"Final Judge [SLAM]: native charge-pillar prefab was not found.");
			yield break;
		}
		float halfWidth = chargePillarWidth * 0.5f;
		int terrainMask = LayerMask.GetMask(new string[1] { "Terrain" });
		Vector2 rayOrigin = new Vector2(origin.x, origin.y + 0.5f);
		RaycastHit2D leftHit = Physics2D.Raycast(rayOrigin, Vector2.left, 100f, terrainMask);
		RaycastHit2D rightHit = Physics2D.Raycast(rayOrigin, Vector2.right, 100f, terrainMask);
		float leftEdge = (((Object)(object)((RaycastHit2D)(ref leftHit)).collider != (Object)null) ? ((RaycastHit2D)(ref leftHit)).point.x : 8f);
		float rightEdge = (((Object)(object)((RaycastHit2D)(ref rightHit)).collider != (Object)null) ? ((RaycastHit2D)(ref rightHit)).point.x : 76f);
		List<float> leftPositions = new List<float>();
		List<float> rightPositions = new List<float>();
		for (float x = origin.x - 3.8f; x >= leftEdge + halfWidth; x -= 3.8f)
		{
			leftPositions.Add(x);
		}
		for (float x2 = origin.x + 3.8f; x2 <= rightEdge - halfWidth; x2 += 3.8f)
		{
			rightPositions.Add(x2);
		}
		int omittedLeft = ((leftPositions.Count > 1) ? Random.Range(1, leftPositions.Count) : (-1));
		int omittedRight = ((rightPositions.Count > 1) ? Random.Range(1, rightPositions.Count) : (-1));
		int tiers = Mathf.Max(leftPositions.Count, rightPositions.Count);
		for (int index = 0; index < tiers; index++)
		{
			if (index < leftPositions.Count && index != omittedLeft)
			{
				ObjectPoolExtensions.Spawn(chargePillarPrefab, new Vector3(leftPositions[index], origin.y, origin.z), Quaternion.identity);
			}
			if (index < rightPositions.Count && index != omittedRight)
			{
				ObjectPoolExtensions.Spawn(chargePillarPrefab, new Vector3(rightPositions[index], origin.y, origin.z), Quaternion.identity);
			}
			if (index + 1 < tiers)
			{
				yield return (object)new WaitForSeconds(0.1f);
			}
		}
		Instance.Log.LogInfo((object)"Final Judge: replaced slam fire waves with outward charge-pillar waves; one pillar was omitted on each side.");
	}

	private static Vector3 FindCenserImpactPosition(Transform judge)
	{
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//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_00e1: 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_0061: Unknown result type (might be due to invalid IL or missing references)
		Transform val = null;
		Transform[] componentsInChildren = ((Component)judge).GetComponentsInChildren<Transform>(true);
		foreach (Transform val2 in componentsInChildren)
		{
			if (((Object)val2).name.IndexOf("Censer", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)(object)val == (Object)null || (((Component)val2).gameObject.activeInHierarchy && !((Component)val).gameObject.activeInHierarchy) || val2.position.y < val.position.y))
			{
				val = val2;
			}
		}
		if ((Object)(object)val != (Object)null)
		{
			Instance.Log.LogInfo((object)("Final Judge: using censer impact object '" + GetHierarchyPath(val) + "'."));
			return val.position;
		}
		Instance.Log.LogWarning((object)"Final Judge [CENSER]: live censer transform was not found; using Judge position.");
		return judge.position;
	}

	private static void SpawnCenserImpactAttack(Vector3 impactPosition)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		bool flag = (Object)(object)judgeHealthManager != (Object)null && judgeHealthManager.hp <= 1100;
		int num = (flag ? 4 : Random.Range(2, 6));
		if (flag && (Object)(object)bombRockPrefab != (Object)null)
		{
			for (int i = 0; i < num; i++)
			{
				Vector2 randomBombRockDirection = GetRandomBombRockDirection();
				SpawnBombRock(impactPosition + Vector2.op_Implicit(randomBombRockDirection * 0.5f), randomBombRockDirection * 30f);
			}
		}
		else if (!flag && (Object)(object)lavaRockPrefab != (Object)null)
		{
			if (!lavaRockPoolConfigured)
			{
				ObjectPool.CreatePool(lavaRockPrefab, 6, false);
				lavaRockPoolConfigured = true;
			}
			float num2 = Random.Range(0f, 360f);
			Vector2 val = default(Vector2);
			for (int j = 0; j < num; j++)
			{
				float num3 = num2 + 360f * (float)j / (float)num;
				float num4 = num3 * ((float)Math.PI / 180f);
				((Vector2)(ref val))..ctor(Mathf.Cos(num4), Mathf.Sin(num4));
				GameObject val2 = ObjectPoolExtensions.Spawn(lavaRockPrefab, impactPosition + Vector2.op_Implicit(val * 0.5f));
				RepairLavaRockSprite(val2);
				DoubleLavaRockDamage(val2);
				MakeProjectilePlayerOnly(val2);
				Rigidbody2D component = val2.GetComponent<Rigidbody2D>();
				if ((Object)(object)component != (Object)null)
				{
					component.linearVelocity = val * 30f;
				}
			}
		}
		((MonoBehaviour)Instance).StartCoroutine(SpawnCenserParticleWaveAndShockwaves(impactPosition));
		Instance.Log.LogInfo((object)("Final Judge: censer impact sprayed " + num + (flag ? " bomb rocks" : " lava rocks") + "; shockwaves follow after " + 0.5f + " seconds."));
	}

	private static IEnumerator SpawnCenserParticleWaveAndShockwaves(Vector3 impactPosition)
	{
		//IL_0007: 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)
		GameObject[] particleWaves = (GameObject[])(object)new GameObject[2];
		for (int index = 0; index < particleWaves.Length; index++)
		{
			GameObject template = stompParticleTemplates[index];
			if (!((Object)(object)template == (Object)null))
			{
				int directionSign = ((index != 0) ? 1 : (-1));
				particleWaves[index] = Object.Instantiate<GameObject>(template);
				particleWaves[index].transform.position = impactPosition + Vector3.right * (2f * (float)directionSign);
				particleWaves[index].SetActive(true);
				ParticleSystem[] componentsInChildren = particleWaves[index].GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem particles in componentsInChildren)
				{
					particles.Play(true);
				}
			}
		}
		float elapsed = 0f;
		while (elapsed < 0.5f)
		{
			float step = Mathf.Min(Time.deltaTime, 0.5f - elapsed);
			for (int j = 0; j < particleWaves.Length; j++)
			{
				if ((Object)(object)particleWaves[j] != (Object)null)
				{
					int directionSign2 = ((j != 0) ? 1 : (-1));
					particleWaves[j].transform.Translate(Vector3.right * ((float)directionSign2 * 180f * step), (Space)0);
				}
			}
			elapsed += step;
			yield return null;
		}
		if ((Object)(object)stompWavePrefab == (Object)null)
		{
			GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
			foreach (GameObject candidate in array)
			{
				if (((Object)candidate).name == "Last Judge Stomp Wave")
				{
					stompWavePrefab = candidate;
					break;
				}
			}
		}
		if ((Object)(object)stompWavePrefab != (Object)null)
		{
			for (int l = -1; l <= 1; l += 2)
			{
				GameObject wave = ObjectPoolExtensions.Spawn(stompWavePrefab, impactPosition, Quaternion.identity);
				Rigidbody2D body = wave.GetComponent<Rigidbody2D>();
				if ((Object)(object)body != (Object)null)
				{
					body.linearVelocity = new Vector2((float)l * stompWaveSpeed, body.linearVelocity.y);
				}
				Vector3 scale = wave.transform.localScale;
				scale.x = Mathf.Abs(scale.x) * (float)l;
				wave.transform.localScale = scale;
			}
		}
		else
		{
			Instance.Log.LogWarning((object)"Final Judge [CENSER]: stomp-wave prefab has not been observed yet.");
		}
		GameObject[] array2 = particleWaves;
		foreach (GameObject particleWave in array2)
		{
			if ((Object)(object)particleWave != (Object)null)
			{
				Object.Destroy((Object)(object)particleWave, 3f);
			}
		}
	}

	private static IEnumerator SpawnSpinLavaRocks(Vector3 origin)
	{
		//IL_0007: 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)
		if ((Object)(object)lavaRockPrefab == (Object)null)
		{
			if (!warnedMissingLavaRock)
			{
				warnedMissingLavaRock = true;
				Instance.Log.LogWarning((object)"Final Judge [LAVA ROCK]: projectile prefab was not ready for the spin.");
			}
			yield break;
		}
		if (!lavaRockPoolConfigured)
		{
			ObjectPool.CreatePool(lavaRockPrefab, 6, false);
			lavaRockPoolConfigured = true;
		}
		for (int index = 0; index < 6; index++)
		{
			float angle = Random.Range(0f, 360f);
			float radians = angle * ((float)Math.PI / 180f);
			Vector2 direction = new Vector2(Mathf.Cos(radians), Mathf.Sin(radians));
			Vector3 spawnPosition = origin + Vector2.op_Implicit(direction * 1.5f);
			GameObject lavaRock = ObjectPoolExtensions.Spawn(lavaRockPrefab, spawnPosition);
			RepairLavaRockSprite(lavaRock);
			DoubleLavaRockDamage(lavaRock);
			MakeProjectilePlayerOnly(lavaRock);
			Rigidbody2D body = lavaRock.GetComponent<Rigidbody2D>();
			if ((Object)(object)body != (Object)null)
			{
				body.linearVelocity = direction * 30f;
			}
			if (index + 1 < 6)
			{
				yield return (object)new WaitForSeconds(0.18f);
			}
		}
		Instance.Log.LogInfo((object)"Final Judge: spawned 6 high-speed DF Lava Rocks at fixed 0.18 second intervals.");
	}

	private static IEnumerator SpawnBombSpiralRocks(PlayMakerFSM controlFsm)
	{
		if ((Object)(object)bombRockPrefab == (Object)null)
		{
			Instance.Log.LogWarning((object)"Final Judge [BOMB SPIRAL]: bomb-rock prefab was not ready.");
			yield break;
		}
		for (int index = 0; index < 8; index++)
		{
			if (!inJudgeFight)
			{
				break;
			}
			if (!((Object)(object)controlFsm != (Object)null))
			{
				break;
			}
			Vector2 direction = GetRandomBombRockDirection();
			Vector3 origin = ((Component)controlFsm).transform.position + Vector2.op_Implicit(direction * 0.75f) + Vector3.up;
			SpawnBombRock(origin, direction * 30f);
			if (index + 1 < 8)
			{
				yield return (object)new WaitForSeconds(0.3f);
			}
		}
		Instance.Log.LogInfo((object)("Final Judge: bomb-rock spiral launched " + 8 + " rocks with random trajectories."));
	}

	private static IEnumerator RunBombSpiralWindow(PlayMakerFSM controlFsm)
	{
		Rigidbody2D body = ((Component)controlFsm).GetComponent<Rigidbody2D>();
		Vector3 holdPosition = ((Component)controlFsm).transform.position;
		((Behaviour)controlFsm).enabled = false;
		((MonoBehaviour)Instance).StartCoroutine(SpawnBombSpiralRocks(controlFsm));
		Instance.Log.LogInfo((object)"Final Judge: thurible spiral began; starting the 3.5-second bomb-rock window.");
		float elapsed = 0f;
		while (elapsed < 3.5f && inJudgeFight && (Object)(object)controlFsm != (Object)null && bombSpiralActive)
		{
			((Component)controlFsm).transform.position = holdPosition;
			if ((Object)(object)body != (Object)null)
			{
				body.linearVelocity = Vector2.zero;
			}
			elapsed += Time.deltaTime;
			yield return null;
		}
		if (!((Object)(object)controlFsm == (Object)null))
		{
			((Behaviour)controlFsm).enabled = true;
			if ((Object)(object)body != (Object)null)
			{
				body.linearVelocity = Vector2.zero;
			}
			if (inJudgeFight && bombSpiralActive)
			{
				bombSpiralActive = false;
				bombSpiralStarted = false;
				controlFsm.SetState("Idle");
				Instance.Log.LogInfo((object)"Final Judge: completed the 3.5-second bomb-rock spiral.");
			}
		}
	}

	private static Vector2 GetRandomBombRockDirection()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		float num;
		do
		{
			num = Random.Range(0f, 360f);
		}
		while (Mathf.Abs(Mathf.DeltaAngle(num, 270f)) < 35f);
		float num2 = num * ((float)Math.PI / 180f);
		return new Vector2(Mathf.Cos(num2), Mathf.Sin(num2));
	}

	private static void RepairLavaRockSprite(GameObject lavaRock)
	{
		if ((Object)(object)lavaRock == (Object)null)
		{
			return;
		}
		tk2dSprite component = lavaRock.GetComponent<tk2dSprite>();
		tk2dSpriteAnimator component2 = lavaRock.GetComponent<tk2dSpriteAnimator>();
		if ((Object)(object)component == (Object)null)
		{
			Instance.Log.LogWarning((object)"Final Judge [LAVA ROCK]: spawned rock has no tk2dSprite component.");
			return;
		}
		tk2dSpriteCollectionData val = ((tk2dBaseSprite)component).Collection;
		int spriteId = ((tk2dBaseSprite)component).spriteId;
		if (((Object)(object)val == (Object)null || !val.IsValidSpriteId(spriteId)) && (Object)(object)component2 != (Object)null)
		{
			tk2dSpriteAnimationClip defaultClip = component2.DefaultClip;
			if (defaultClip != null && defaultClip.frames != null && defaultClip.frames.Length != 0)
			{
				val = defaultClip.frames[0].spriteCollection;
				spriteId = defaultClip.frames[0].spriteId;
			}
		}
		if ((Object)(object)val == (Object)null || !val.IsValidSpriteId(spriteId))
		{
			Instance.Log.LogWarning((object)"Final Judge [LAVA ROCK]: no valid tk2d sprite collection/frame was available.");
			return;
		}
		((tk2dBaseSprite)component).SetSprite(val, spriteId);
		((tk2dBaseSprite)component).ForceBuild();
		Renderer component3 = ((Component)component).GetComponent<Renderer>();
		if ((Object)(object)component3 != (Object)null)
		{
			component3.enabled = true;
		}
	}

	private static void DoubleLavaRockDamage(GameObject lavaRock)
	{
		if ((Object)(object)lavaRock == (Object)null || DamageDealtField == null)
		{
			return;
		}
		DamageHero[] componentsInChildren = lavaRock.GetComponentsInChildren<DamageHero>(true);
		foreach (DamageHero val in componentsInChildren)
		{
			if (doubledLavaRockDamagers.Add(((Object)val).GetInstanceID()))
			{
				int num = (int)DamageDealtField.GetValue(val);
				val.SetDamageAmount(num * 2);
			}
		}
	}

	private static void SpawnBombRock(Vector3 position, Vector2 velocity)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)bombRockPrefab == (Object)null))
		{
			GameObject val = ObjectPoolExtensions.Spawn(bombRockPrefab, position);
			RepairLavaRockSprite(val);
			RepairBombRockParticleMaterials(val);
			MakeProjectilePlayerOnly(val);
			Rigidbody2D component = val.GetComponent<Rigidbody2D>();
			if ((Object)(object)component != (Object)null)
			{
				component.linearVelocity = velocity;
			}
		}
	}

	private static void RepairBombRockParticleMaterials(GameObject bombRock)
	{
		ParticleSystemRenderer[] componentsInChildren = bombRock.GetComponentsInChildren<ParticleSystemRenderer>(true);
		foreach (ParticleSystemRenderer val in componentsInChildren)
		{
			bool flag = ((Renderer)val).sharedMaterials.Length == 0;
			Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
			foreach (Material val2 in sharedMaterials)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.shader == (Object)null || !val2.shader.isSupported || (Object)(object)val2.mainTexture == (Object)null)
				{
					flag = true;
					break;
				}
			}
			if (flag)
			{
				((Renderer)val).enabled = false;
			}
		}
	}

	private static void MakeProjectilePlayerOnly(GameObject projectile)
	{
		if (!((Object)(object)projectile == (Object)null))
		{
			DamageEnemies[] componentsInChildren = projectile.GetComponentsInChildren<DamageEnemies>(true);
			foreach (DamageEnemies val in componentsInChildren)
			{
				((Behaviour)val).enabled = false;
			}
			FireballProjectile[] componentsInChildren2 = projectile.GetComponentsInChildren<FireballProjectile>(true);
			foreach (FireballProjectile val2 in componentsInChildren2)
			{
				((object)val2).GetType().GetField("enemyDamageAmount", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(val2, 0);
			}
		}
	}

	private static void ArmNativeFourWaveSpin(PlayMakerFSM controlFsm)
	{
		FsmState state = controlFsm.Fsm.GetState("Rerage?");
		if (state == null)
		{
			return;
		}
		FsmStateAction[] actions = state.Actions;
		foreach (FsmStateAction val in actions)
		{
			FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				object value = fieldInfo.GetValue(val);
				if (((object)val).GetType().Name == "BoolTest" && fieldInfo.Name == "boolVariable")
				{
					FsmBool val2 = (FsmBool)((value is FsmBool) ? value : null);
					if (val2 != null)
					{
						val2.Value = true;
						continue;
					}
				}
				if (((object)val).GetType().Name == "IntAdd" && fieldInfo.Name == "intVariable")
				{
					FsmInt val3 = (FsmInt)((value is FsmInt) ? value : null);
					if (val3 != null)
					{
						val3.Value = 4;
					}
				}
			}
		}
		Instance.Log.LogInfo((object)"Final Judge: armed the native four-wave rage spin below 1100 HP.");
	}

	private static IEnumerator ControlExtendedCharge(PlayMakerFSM controlFsm, float duration)
	{
		Rigidbody2D body = ((Component)controlFsm).GetComponent<Rigidbody2D>();
		Transform chargeCollider = FindNamedChild(((Component)controlFsm).transform, "Charge Collider");
		float elapsed = 0f;
		while (elapsed < duration && inJudgeFight && (Object)(object)controlFsm != (Object)null && controlFsm.ActiveStateName == "Charge")
		{
			EnsureChargeContactDamage(chargeCollider);
			if ((Object)(object)body != (Object)null)
			{
				float direction = Mathf.Sign(body.linearVelocity.x);
				if (direction == 0f)
				{
					direction = 0f - Mathf.Sign(((Component)controlFsm).transform.localScale.x);
				}
				int terrainMask = LayerMask.GetMask(new string[1] { "Terrain" });
				Vector2 rayOrigin = new Vector2(((Component)controlFsm).transform.position.x, ((Component)controlFsm).transform.position.y + 1f);
				RaycastHit2D wall = Physics2D.Raycast(rayOrigin, Vector2.right * direction, 2.5f, terrainMask);
				if ((Object)(object)((RaycastHit2D)(ref wall)).collider != (Object)null)
				{
					Vector3 scale = ((Component)controlFsm).transform.localScale;
					scale.x *= -1f;
					((Component)controlFsm).transform.localScale = scale;
					body.linearVelocity = new Vector2((0f - direction) * 40f, body.linearVelocity.y);
					Transform transform = ((Component)controlFsm).transform;
					transform.position += Vector3.right * ((0f - direction) * 0.2f);
				}
				wall = default(RaycastHit2D);
			}
			elapsed += Time.deltaTime;
			yield return null;
		}
		extendedChargeRunning = false;
		Instance.Log.LogInfo((object)("Final Judge: completed the " + duration + "-second wall-bouncing charge."));
	}

	private static IEnumerator MaintainChargeContactDamage(PlayMakerFSM controlFsm)
	{
		Transform chargeCollider = FindNamedChild(((Component)controlFsm).transform, "Charge Collider");
		while (inJudgeFight && (Object)(object)controlFsm != (Object)null && controlFsm.ActiveStateName == "Charge")
		{
			if ((Object)(object)judgeHealthManager != (Object)null)
			{
				judgeHealthManager.IsInvincible = false;
			}
			EnsureChargeContactDamage(chargeCollider);
			EnsureNamedChargeDamagers(((Component)controlFsm).transform);
			yield return null;
		}
		chargeDamageMaintenanceRunning = false;
	}

	private static IEnumerator MaintainFinalPhaseContactDamage(PlayMakerFSM controlFsm)
	{
		while (inJudgeFight && (Object)(object)controlFsm != (Object)null && (Object)(object)judgeHealthManager != (Object)null)
		{
			foreach (DamageHero damager in baselineContactDamagers)
			{
				if ((Object)(object)damager == (Object)null)
				{
					continue;
				}
				((Component)damager).gameObject.SetActive(true);
				((Behaviour)damager).enabled = true;
				if (DamageDealtField != null)
				{
					int damage = (int)DamageDealtField.GetValue(damager);
					if (damage < 1)
					{
						damager.SetDamageAmount(1);
					}
				}
				Collider2D[] componentsInChildren = ((Component)damager).GetComponentsInChildren<Collider2D>(true);
				foreach (Collider2D collider in componentsInChildren)
				{
					((Behaviour)collider).enabled = true;
				}
			}
			yield return null;
		}
		finalPhaseContactMaintenanceRunning = false;
	}

	private static void CacheBaselineContactDamagers(Transform bossRoot)
	{
		if ((Object)(object)bossRoot == (Object)null || baselineContactDamagers.Count > 0)
		{
			return;
		}
		DamageHero[] componentsInChildren = ((Component)bossRoot).GetComponentsInChildren<DamageHero>(true);
		foreach (DamageHero val in componentsInChildren)
		{
			if (((Component)val).gameObject.activeInHierarchy && ((Behaviour)val).enabled)
			{
				baselineContactDamagers.Add(val);
			}
		}
		Instance.Log.LogInfo((object)("Final Judge: cached " + baselineContactDamagers.Count + " active pre-roar contact damagers for phase preservation."));
	}

	private static Transform FindNamedChild(Transform root, string childName)
	{
		Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
		foreach (Transform val in componentsInChildren)
		{
			if (((Object)val).name == childName)
			{
				return val;
			}
		}
		return null;
	}

	private static void EnsureChargeContactDamage(Transform chargeCollider)
	{
		if ((Object)(object)chargeCollider == (Object)null)
		{
			return;
		}
		((Component)chargeCollider).gameObject.SetActive(true);
		Collider2D[] componentsInChildren = ((Component)chargeCollider).GetComponentsInChildren<Collider2D>(true);
		foreach (Collider2D val in componentsInChildren)
		{
			((Behaviour)val).enabled = true;
		}
		DamageHero[] componentsInChildren2 = ((Component)chargeCollider).GetComponentsInChildren<DamageHero>(true);
		foreach (DamageHero val2 in componentsInChildren2)
		{
			((Behaviour)val2).enabled = true;
			if (DamageDealtField != null)
			{
				int num = (int)DamageDealtField.GetValue(val2);
				if (num < 1)
				{
					val2.SetDamageAmount(1);
				}
			}
		}
	}

	private static void EnsureNamedChargeDamagers(Transform bossRoot)
	{
		DamageHero[] componentsInChildren = ((Component)bossRoot).GetComponentsInChildren<DamageHero>(true);
		foreach (DamageHero val in componentsInChildren)
		{
			if (GetHierarchyPath(((Component)val).transform).IndexOf("Charge", StringComparison.OrdinalIgnoreCase) < 0)
			{
				continue;
			}
			((Component)val).gameObject.SetActive(true);
			((Behaviour)val).enabled = true;
			Collider2D[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Collider2D>(true);
			foreach (Collider2D val2 in componentsInChildren2)
			{
				((Behaviour)val2).enabled = true;
			}
			if (DamageDealtField != null)
			{
				int num = (int)DamageDealtField.GetValue(val);
				if (num < 1)
				{
					val.SetDamageAmount(1);
				}
			}
		}
	}

	private static void SetFsmFloatField(FsmStateAction action, string fieldName, float value)
	{
		object? obj = ((object)action).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(action);
		FsmFloat val = (FsmFloat)((obj is FsmFloat) ? obj : null);
		if (val != null)
		{
			val.Value = value;
		}
	}

	private static void ConfigureFieryPhase(PlayMakerFSM controlFsm)
	{
		if (!fieryPhaseConfigured && !((Object)(object)controlFsm == (Object)null))
		{
			FsmBool val = controlFsm.FsmVariables.FindFsmBool("Flamed Up");
			if (val == null)
			{
				Instance.Log.LogWarning((object)"Final Judge [PHASE]: Control FSM variable 'Flamed Up' was not found.");
				return;
			}
			val.Value = true;
			fieryPhaseConfigured = true;
			Instance.Log.LogInfo((object)"Final Judge: enabled the native 'Flamed Up' phase at fight startup; fiery attacks are active.");
		}
	}

	private static void CacheStompParticleTemplates(PlayMakerFSM controlFsm)
	{
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Invalid comparison between Unknown and I4
		if ((Object)(object)controlFsm == (Object)null || (Object)(object)stompParticleTemplates[0] != (Object)null)
		{
			return;
		}
		FsmState state = controlFsm.Fsm.GetState("Stomp Flame Antic");
		if (state == null)
		{
			return;
		}
		int num = 0;
		FsmStateAction[] actions = state.Actions;
		foreach (FsmStateAction val in actions)
		{
			if (((object)val).GetType().Name != "PlayParticleEmitter" || num >= stompParticleTemplates.Length)
			{
				continue;
			}
			FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				object? value = fieldInfo.GetValue(val);
				FsmOwnerDefault val2 = (FsmOwnerDefault)((value is FsmOwnerDefault) ? value : null);
				if (val2 != null)
				{
					GameObject val3 = ((val2.GameObject != null) ? val2.GameObject.Value : null);
					if ((Object)(object)val3 == (Object)null && (int)val2.OwnerOption == 0)
					{
						val3 = ((Component)controlFsm).gameObject;
					}
					if ((Object)(object)val3 != (Object)null)
					{
						stompParticleTemplates[num++] = val3;
						break;
					}
				}
			}
		}
		Instance.Log.LogInfo((object)("Final Judge: cached " + num + " native stomp particle-wave emitters."));
	}

	private static void CacheChargePillarPrefab(PlayMakerFSM controlFsm)
	{
		if ((Object)(object)chargePillarPrefab != (Object)null || (Object)(object)controlFsm == (Object)null)
		{
			return;
		}
		FsmState state = controlFsm.Fsm.GetState("Charge");
		if (state == null)
		{
			return;
		}
		FsmStateAction[] actions = state.Actions;
		foreach (FsmStateAction val in actions)
		{
			FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				object? value = fieldInfo.GetValue(val);
				FsmGameObject val2 = (FsmGameObject)((value is FsmGameObject) ? value : null);
				if (val2 != null && (Object)(object)val2.Value != (Object)null && ((Object)val2.Value).name == "Last Judge Charge Bomb")
				{
					chargePillarPrefab = val2.Value;
					Instance.Log.LogInfo((object)"Final Judge: cached native charge-pillar prefab from the Charge state.");
					return;
				}
			}
		}
	}

	private static void ConfigureChargePillarTrail(PlayMakerFSM controlFsm)
	{
		if (chargePillarTrailConfigured || (Object)(object)controlFsm == (Object)null)
		{
			return;
		}
		FsmState state = controlFsm.Fsm.GetState("Charge");
		if (state == null)
		{
			return;
		}
		FsmStateAction[] actions = state.Actions;
		foreach (FsmStateAction val in actions)
		{
			if (!(((object)val).GetType().Name != "SpawnObjectFromGlobalPoolOverTime"))
			{
				object? obj = ((object)val).GetType().GetField("frequency", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(val);
				FsmFloat val2 = (FsmFloat)((obj is FsmFloat) ? obj : null);
				if (val2 != null)
				{
					val2.Value = 0.095f;
					chargePillarTrailConfigured = true;
					Instance.Log.LogInfo((object)("Final Judge: changed charge pillar interval from 0.2 to " + 0.095f + " seconds for 3.8-unit spacing."));
					return;
				}
			}
		}
		Instance.Log.LogWarning((object)"Final Judge [CHARGE]: over-time pillar spawn action was not found.");
	}

	private static void ScheduleThresholdRageIfNeeded(PlayMakerFSM controlFsm)
	{
		if (rageTransitionScheduled || (Object)(object)controlFsm == (Object)null || (Object)(object)judgeHealthManager == (Object)null)
		{
			return;
		}
		int threshold;
		if (!rageAt1100Triggered && judgeHealthManager.hp <= 1100)
		{
			rageAt1100Triggered = true;
			threshold = 1100;
		}
		else
		{
			if (!rageAt1100Triggered || rageAt400Triggered || judgeHealthManager.hp > 600)
			{
				return;
			}
			rageAt400Triggered = true;
			threshold = 600;
		}
		rageTransitionScheduled = true;
		((MonoBehaviour)Instance).StartCoroutine(EnterNativeRageRoar(controlFsm, threshold));
	}

	private static IEnumerator EnterNativeRageRoar(PlayMakerFSM controlFsm, int threshold)
	{
		yield return null;
		rageTransitionScheduled = false;
		if (!inJudgeFight || (Object)(object)controlFsm == (Object)null)
		{
			yield break;
		}
		CacheBaselineContactDamagers(((Component)controlFsm).transform);
		if (!finalPhaseContactMaintenanceRunning)
		{
			finalPhaseContactMaintenanceRunning = true;
			((MonoBehaviour)Instance).StartCoroutine(MaintainFinalPhaseContactDamage(controlFsm));
		}
		if (threshold == 600)
		{
			postFinalPhaseRoarChargePending = true;
			FsmState rageRoar2 = controlFsm.Fsm.GetState("Rage Roar 2");
			if (rageRoar2 != null)
			{
				FsmTransition[] transitions = rageRoar2.Transitions;
				foreach (FsmTransition transition in transitions)
				{
					if (transition.EventName == "FINISHED")
					{
						transition.ToState = "Charge Antic 1";
						transition.ToFsmState = controlFsm.Fsm.GetState("Charge Antic 1");
						restoreRageRoarTransitionOnCharge = true;
						break;
					}
				}
			}
		}
		controlFsm.SetState("Rage Roar 1");
		if (threshold == 600)
		{
			((MonoBehaviour)Instance).StartCoroutine(ReplayNativeRoarAudio(controlFsm));
		}
		Instance.Log.LogInfo((object)("Final Judge: triggered native rage roar and white circles at " + threshold + " HP."));
	}

	private static IEnumerator ReplayNativeRoarAudio(PlayMakerFSM controlFsm)
	{
		yield return null;
		if (!inJudgeFight || (Object)(object)controlFsm == (Object)null)
		{
			yield break;
		}
		FsmState roarState = controlFsm.Fsm.GetState("Rage Roar 1");
		int replayedActions = 0;
		if (roarState != null)
		{
			FsmStateAction[] actions = roarState.Actions;
			foreach (FsmStateAction action in actions)
			{
				string actionName = ((object)action).GetType().Name;
				if (action.Enabled && actionName.IndexOf("Audio", StringComparison.OrdinalIgnoreCase) >= 0 && actionName.IndexOf("Play", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					action.OnEnter();
					replayedActions++;
				}
			}
		}
		Instance.Log.LogInfo((object)("Final Judge: replayed " + replayedActions + " native roar audio actions for the 600 HP roar."));
	}

	private static void RestoreRageRoarTransition(PlayMakerFSM controlFsm)
	{
		FsmState state = controlFsm.Fsm.GetState("Rage Roar 2");
		if (state != null)
		{
			FsmTransition[] transitions = state.Transitions;
			foreach (FsmTransition val in transitions)
			{
				if (val.EventName == "FINISHED")
				{
					val.ToState = "Spin Antic";
					val.ToFsmState = controlFsm.Fsm.GetState("Spin Antic");
					break;
				}
			}
		}
		restoreRageRoarTransitionOnCharge = false;
	}

	private static void ConfigureNoStaggers(PlayMakerFSM controlFsm)
	{
		if (noStaggersConfigured || (Object)(object)controlFsm == (Object)null)
		{
			return;
		}
		FsmState state = controlFsm.Fsm.GetState("Idle");
		if (state == null)
		{
			return;
		}
		int num = 0;
		FsmState[] states = controlFsm.Fsm.States;
		foreach (FsmState val in states)
		{
			FsmTransition[] transitions = val.Transitions;
			foreach (FsmTransition val2 in transitions)
			{
				if (val2.ToState.IndexOf("Stun", StringComparison.OrdinalIgnoreCase) >= 0 || val2.ToState.IndexOf("Stagger", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val2.ToState = "Idle";
					val2.ToFsmState = state;
					num++;
				}
			}
		}
		noStaggersConfigured = true;
		ClearJudgeStaggerIndicators(((Component)controlFsm).transform);
		if (!staggerIndicatorSuppressionRunning)
		{
			staggerIndicatorSuppressionRunning = true;
			((MonoBehaviour)Instance).StartCoroutine(MaintainStaggerIndicatorSuppression(((Component)controlFsm).transform));
		}
		Instance.Log.LogInfo((object)("Final Judge: redirected " + num + " stagger transitions directly to Idle."));
	}

	private static void ClearJudgeStaggerIndicators(Transform bossRoot)
	{
		FSMActivator[] componentsInChildren = ((Component)bossRoot).GetComponentsInChildren<FSMActivator>(true);
		foreach (FSMActivator val in componentsInChildren)
		{
			if (((object)val).GetType().GetMethod("DeactivateStaggered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)?.Invoke(val, null) is IEnumerator enumerator)
			{
				((MonoBehaviour)Instance).StartCoroutine(enumerator);
			}
		}
		DisableNamedStaggerVisuals(bossRoot);
	}

	private static IEnumerator MaintainStaggerIndicatorSuppression(Transform bossRoot)
	{
		while (inJudgeFight && (Object)(object)bossRoot != (Object)null)
		{
			DisableNamedStaggerVisuals(bossRoot);
			yield return null;
		}
		staggerIndicatorSuppressionRunning = false;
	}

	private static void DisableNamedStaggerVisuals(Transform bossRoot)
	{
		PlayMakerFSM[] componentsInChildren = ((Component)bossRoot).GetComponentsInChildren<PlayMakerFSM>(true);
		foreach (PlayMakerFSM val in componentsInChildren)
		{
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)bossControlFsm) && (IsStaggerIndicatorName(val.FsmName) || IsStaggerIndicatorName(((Object)((Component)val).gameObject).name)))
			{
				((Behaviour)val).enabled = false;
				if ((Object)(object)((Component)val).transform != (Object)(object)bossRoot)
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}
		Renderer[] componentsInChildren2 = ((Component)bossRoot).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val2 in componentsInChildren2)
		{
			if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).transform != (Object)(object)bossRoot && IsStaggerIndicatorName(GetHierarchyPath(((Component)val2).transform)))
			{
				val2.enabled = false;
				((Component)val2).gameObject.SetActive(false);
			}
		}
	}

	private static bool IsStaggerIndicatorName(string value)
	{
		return !string.IsNullOrEmpty(value) && (value.IndexOf("Stun", StringComparison.OrdinalIgnoreCase) >= 0 || value.IndexOf("Stagger", StringComparison.OrdinalIgnoreCase) >= 0 || value.IndexOf("Daze", StringComparison.OrdinalIgnoreCase) >= 0 || value.IndexOf("Dizzy", StringComparison.OrdinalIgnoreCase) >= 0);
	}

	private static IEnumerator EscapeStaggerState(PlayMakerFSM controlFsm)
	{
		yield return null;
		staggerEscapeScheduled = false;
		if (inJudgeFight && (Object)(object)controlFsm != (Object)null)
		{
			RestoreJudgeGravity(controlFsm);
			controlFsm.SetState("Idle");
			yield return null;
			RestoreJudgeGravity(controlFsm);
		}
	}

	private static void RestoreJudgeGravity(PlayMakerFSM controlFsm)
	{
		Rigidbody2D val = (((Object)(object)controlFsm != (Object)null) ? ((Component)controlFsm).GetComponent<Rigidbody2D>() : null);
		if (!((Object)(object)val == (Object)null))
		{
			val.simulated = true;
			val.gravityScale = Mathf.Max(judgeGravityScale, 0.01f);
			Instance.Log.LogInfo((object)("Final Judge: restored gravity after stagger (scale " + val.gravityScale + ")."));
		}
	}

	private static void RemoveNativeStompAntic(PlayMakerFSM controlFsm)
	{
		if (nativeStompAnticRemoved || (Object)(object)controlFsm == (Object)null)
		{
			return;
		}
		FsmState state = controlFsm.Fsm.GetState("Stomp Flame Antic");
		if (state == null)
		{
			return;
		}
		FsmStateAction[] actions = state.Actions;
		foreach (FsmStateAction val in actions)
		{
			if (((object)val).GetType().Name != "Wait")
			{
				val.Enabled = false;
			}
		}
		nativeStompAnticRemoved = true;
		Instance.Log.LogInfo((object)"Final Judge: removed the original slam particle antic while retaining its 0.5-second timing.");
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(SetHP), "OnEnter")]
	private static void ReplaceJudgeStartingHealth(SetHP __instance)
	{
		if (inJudgeFight && __instance?.hp != null)
		{
			GameObject safe = FSMUtility.GetSafe(__instance.target, (FsmStateAction)(object)__instance);
			Fsm fsm = ((FsmStateAction)__instance).Fsm;
			PlayMakerFSM val = ((fsm != null) ? fsm.FsmComponent : null);
			if (((Object)(object)safe != (Object)null && IsJudgeHierarchy(safe.transform)) || ((Object)(object)val != (Object)null && IsJudgeHierarchy(((Component)val).transform)))
			{
				int value = __instance.hp.Value;
				__instance.hp.Value = 1500;
				Instance.Log.LogInfo((object)("Final Judge: changed Last Judge SetHP from " + value + " to " + 1500 + "."));
			}
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DisplayBossTitle), "OnEnter")]
	private static void ArmJudgeBossTitleReplacement(DisplayBossTitle __instance)
	{
		object obj;
		if (__instance == null)
		{
			obj = null;
		}
		else
		{
			Fsm fsm = ((FsmStateAction)__instance).Fsm;
			obj = ((fsm != null) ? fsm.FsmComponent : null);
		}
		PlayMakerFSM val = (PlayMakerFSM)obj;
		if (inJudgeFight && !((Object)(object)val == (Object)null) && IsJudgeHierarchy(((Component)val).transform))
		{
			replaceBossTitleLocalization = true;
			Instance.Log.LogInfo((object)("Final Judge [TITLE]: armed replacement for boss-title event '" + __instance.bossTitle.Value + "'."));
			((MonoBehaviour)Instance).StartCoroutine(EndJudgeBossTitleReplacementWindow());
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(Language), "Get", new Type[]
	{
		typeof(string),
		typeof(string)
	})]
	private static void ReplaceJudgeBossTitleLocalization(string key, string sheetTitle, ref string __result)
	{
		if (replaceBossTitleLocalization && !string.IsNullOrEmpty(__result))
		{
			string text = __result.Trim();
			bool flag = !string.IsNullOrEmpty(key) && key.IndexOf("LAST_JUDGE", StringComparison.OrdinalIgnoreCase) >= 0;
			bool flag2 = text.IndexOf("Last Judge", StringComparison.OrdinalIgnoreCase) >= 0 || (flag && (key.IndexOf("MAIN", StringComparison.OrdinalIgnoreCase) >= 0 || key.IndexOf("NAME", StringComparison.OrdinalIgnoreCase) >= 0));
			Instance.Log.LogInfo((object)("Final Judge [TITLE]: localization key='" + key + "', sheet='" + sheetTitle + "', value='" + __result + "'."));
			if (flag2)
			{
				__result = "Final Judge";
			}
			else if (flag || string.Equals(text, "The", StringComparison.OrdinalIgnoreCase))
			{
				__result = "Harbinger of Sin";
			}
		}
	}

	private static IEnumerator EndJudgeBossTitleReplacementWindow()
	{
		yield return (object)new WaitForSeconds(3f);
		replaceBossTitleLocalization = false;
		Instance.Log.LogInfo((object)"Final Judge: applied localized two-line boss title replacement window.");
	}

	private static IEnumerator FindAndSetJudgeHealth()
	{
		for (int frame = 0; frame < 120; frame++)
		{
			HealthManager[] array = Resources.FindObjectsOfTypeAll<HealthManager>();
			foreach (HealthManager healthManager in array)
			{
				int num2;
				if (!((Object)(object)healthManager == (Object)null))
				{
					Scene scene = ((Component)healthManager).gameObject.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						scene = ((Component)healthManager).gameObject.scene;
						if (!(((Scene)(ref scene)).name != "Coral_Judge_Arena"))
						{
							num2 = ((!IsJudgeHierarchy(((Component)healthManager).transform)) ? 1 : 0);
							goto IL_00be;
						}
					}
				}
				num2 = 1;
				goto IL_00be;
				IL_00be:
				if (num2 == 0)
				{
					int originalHealth = healthManager.hp;
					healthManager.hp = 1500;
					Traverse.Create((object)healthManager).Field("initHp").SetValue((object)1500);
					judgeHealthManager = healthManager;
					healthSetupRunning = false;
					healthConfigured = true;
					Instance.Log.LogInfo((object)("Final Judge: changed live Last Judge health from " + originalHealth + " to " + 1500 + " at " + GetHierarchyPath(((Component)healthManager).transform) + "."));
					yield break;
				}
			}
			yield return null;
		}
		healthSetupRunning = false;
		Instance.Log.LogWarning((object)"Final Judge [HEALTH]: no Last Judge HealthManager appeared during startup.");
	}

	private static bool IsJudgeHierarchy(Transform transform)
	{
		while ((Object)(object)transform != (Object)null)
		{
			if (string.Equals(((Object)transform).name, "Last Judge", StringComparison.Ordinal) || ((Object)transform).name.IndexOf("Last Judge", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			transform = transform.parent;
		}
		return false;
	}

	private static string GetHierarchyPath(Transform transform)
	{
		string text = (((Object)(object)transform == (Object)null) ? "<null>" : ((Object)transform).name);
		while ((Object)(object)((transform != null) ? transform.parent : null) != (Object)null)
		{
			transform = transform.parent;
			text = ((Object)transform).name + "/" + text;
		}
		return text;
	}
}