Decompiled source of SlipSkid FastIntermissions v0.1.4

BepInEx/plugins/SlipSkid-FastIntermissions/SlipSkid.FastIntermissions.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Unity.Mono;
using Game;
using Game.Scores;
using HarmonyLib;
using Menus;
using Obstacles;
using TMPro;
using UI;
using UI.ScoreBoard;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace SlipSkid.FastIntermissions;

[BepInPlugin("slipskid.fastintermissions", "Slip & Skid - Fast Intermissions", "0.1.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class FastIntermissionsPlugin : BaseUnityPlugin
{
	private sealed class PlacementRoutine
	{
		internal Obstacle owner;
	}

	[HarmonyPatch]
	private static class ScatterCompletionPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			yield return AccessTools.Method(typeof(ObstacleScatter), "ScatterCoroutine", (Type[])null, (Type[])null);
			yield return AccessTools.Method(typeof(ObstacleControlledScatter), "ScatterCoroutine", (Type[])null, (Type[])null);
		}

		private static void Postfix(Obstacle __instance, ref IEnumerator __result)
		{
			__result = TrackPlacementRoutine(__instance, __result);
		}
	}

	[HarmonyPatch]
	private static class ScoreBoardWaitsPatch
	{
		private static MethodBase TargetMethod()
		{
			return FindStateMachineMoveNext(typeof(ScoreBoardMenu), "UpdateScoresRoutine");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return ScaleScoreBoardRoutine(instructions);
		}
	}

	[HarmonyPatch]
	private static class PlayerScoreAnimationPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(PlayerScoreElement), "Animate", (Type[])null, (Type[])null);
		}

		private static void Prefix(object[] __args)
		{
			ScaleFloatArgument(__args, 6, ScaleScoreDelay);
		}
	}

	[HarmonyPatch]
	private static class ScoreReorderAnimationPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(FloatingLayout), "Reorder", (Type[])null, (Type[])null);
		}

		private static void Prefix(object[] __args)
		{
			ScaleFloatArgument(__args, 1, ScaleScoreDelay);
		}
	}

	[HarmonyPatch]
	private static class PreScoreBoardPausePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindStateMachineMoveNext(typeof(GameManager), "WaitAndGoToScoreBoard");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return ScaleWaits(instructions, IntermissionDelayScaler, "Pause avant le classement", 1);
		}
	}

	[HarmonyPatch]
	private static class PostPlacementPausePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindStateMachineMoveNext(typeof(GameManager), "WaitAndGoToResetPlayers");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if (Calls(item, WaitForSecondsConstructor))
				{
					item.opcode = OpCodes.Call;
					item.operand = PlacementWaitFactory;
					num++;
				}
			}
			LogPatchResult("Attente après le placement des objets", num, 1);
			return list;
		}
	}

	[HarmonyPatch]
	private static class PostSelectionPausePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindStateMachineMoveNext(typeof(GameManager), "WaitAndGoToPlacingObstacles");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return ScaleWaits(instructions, IntermissionDelayScaler, "Pause après le choix des objets", 1);
		}
	}

	[HarmonyPatch]
	private static class RoundIntroPausePatch
	{
		private static MethodBase TargetMethod()
		{
			return FindStateMachineMoveNext(typeof(GameManager), "StartRoundCoroutine");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return ScaleWaits(instructions, IntermissionDelayScaler, "Pauses d'introduction de la manche", 4);
		}
	}

	[HarmonyPatch]
	private static class FullScreenTransitionPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(InGameMenu), "StartTransition", (Type[])null, (Type[])null);
		}

		private static void Prefix(object[] __args)
		{
			ScaleFloatArgument(__args, 3, ScaleTransitionDelay);
			ScaleFloatArgument(__args, 4, ScaleTransitionDelay);
			ScaleFloatArgument(__args, 5, ScaleTransitionDelay);
		}
	}

	[HarmonyPatch]
	private static class FinalPlatformAnimationPatch
	{
		private static MethodBase TargetMethod()
		{
			return FindStateMachineMoveNext(typeof(EndGamePlatform), "AnimateEndRoutine");
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return ScaleWaits(instructions, IntermissionDelayScaler, "Animation du podium final", 2);
		}
	}

	[HarmonyPatch]
	private static class FinalResultsDurationPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.Method(typeof(InGameMenu), "ShowEndGame", (Type[])null, (Type[])null);
		}

		private static void Prefix(object[] __args)
		{
			if (__args != null && __args.Length != 0)
			{
				object obj = __args[0];
				float val = default(float);
				int num;
				if (obj is float)
				{
					val = (float)obj;
					num = 1;
				}
				else
				{
					num = 0;
				}
				if (num != 0)
				{
					__args[0] = Math.Min(val, 12f);
				}
			}
		}
	}

	[HarmonyPatch(typeof(ScoreBoardMenu), "Show")]
	private static class PrepareScorePresentationPatch
	{
		private static void Prefix(ScoreBoardMenu __instance)
		{
			PlayerScoreIndicator[] playersScoreIndicators = __instance.playersScoreIndicators;
			foreach (PlayerScoreIndicator val in playersScoreIndicators)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.positionEase == (Object)null))
				{
					val.positionEase.damping = 1f;
					val.positionEase.initializationFactor = 0f;
				}
			}
			bool flag = __instance.playersScoreElements.Length <= 4;
			PlayerScoreElement[] playersScoreElements = __instance.playersScoreElements;
			foreach (PlayerScoreElement val2 in playersScoreElements)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.labelsHolder == (Object)null)
				{
					continue;
				}
				FastNativeScoreLayout fastNativeScoreLayout = ((Component)val2.labelsHolder).GetComponent<FastNativeScoreLayout>();
				if (flag && (Object)(object)fastNativeScoreLayout == (Object)null)
				{
					fastNativeScoreLayout = ((Component)val2.labelsHolder).gameObject.AddComponent<FastNativeScoreLayout>();
				}
				if (!((Object)(object)fastNativeScoreLayout == (Object)null))
				{
					((Behaviour)fastNativeScoreLayout).enabled = flag;
					if (flag)
					{
						fastNativeScoreLayout.Bind(val2);
					}
				}
			}
		}
	}

	[HarmonyPatch(typeof(PlayerScoreElement), "Reset")]
	private static class NativeScoreSequencePatch
	{
		private static void Postfix(PlayerScoreElement __instance, PlayerScore playerScore)
		{
			FastNativeScoreLayout component = ((Component)__instance.labelsHolder).GetComponent<FastNativeScoreLayout>();
			GameManager instance = GameManager.instance;
			if (!((Object)(object)component == (Object)null) && ((Behaviour)component).enabled && !((Object)(object)instance == (Object)null) && !((Object)(object)instance.networkVariables == (Object)null))
			{
				if ((Object)(object)__instance.playerScoreIndicator != (Object)null)
				{
					__instance.scoreLabel.text = __instance.playerScoreIndicator.scoreLabel.text;
				}
				component.longSequence = ((PlayerScore)(ref playerScore)).GetChunks(instance.networkVariables.roundIndex.Value).Count((ScoreChunk chunk) => chunk.scoreDisplay != 0 || chunk.scoreForceDisplay) > 6;
			}
		}
	}

	[HarmonyPatch(typeof(FloatingTextLabel), "Init")]
	private static class NativeScoreLabelPatch
	{
		private static void Prefix(Transform parent, ref float duration)
		{
			FastNativeScoreLayout fastNativeScoreLayout = (((Object)(object)parent == (Object)null) ? null : ((Component)parent).GetComponent<FastNativeScoreLayout>());
			if ((Object)(object)fastNativeScoreLayout != (Object)null && ((Behaviour)fastNativeScoreLayout).enabled && fastNativeScoreLayout.longSequence)
			{
				duration = ScaleScoreDelay(1.8f);
			}
		}

		private static void Postfix(FloatingTextLabel __instance, Transform parent)
		{
			FastNativeScoreLayout fastNativeScoreLayout = (((Object)(object)parent == (Object)null) ? null : ((Component)parent).GetComponent<FastNativeScoreLayout>());
			if (!((Object)(object)fastNativeScoreLayout == (Object)null) && ((Behaviour)fastNativeScoreLayout).enabled)
			{
				FastNativeScoreLabel fastNativeScoreLabel = ((Component)__instance.mainContainer).GetComponent<FastNativeScoreLabel>();
				if ((Object)(object)fastNativeScoreLabel == (Object)null)
				{
					fastNativeScoreLabel = ((Component)__instance.mainContainer).gameObject.AddComponent<FastNativeScoreLabel>();
				}
				fastNativeScoreLabel.Bind(__instance);
				fastNativeScoreLayout.Refresh();
			}
		}
	}

	[HarmonyPatch(typeof(FloatingTextLabelGenerator), "CleanUp")]
	private static class RestoreNativeLabelPatch
	{
		private static void Prefix(FloatingTextLabel floatingTextLabel)
		{
			if ((Object)(object)floatingTextLabel != (Object)null)
			{
				((Component)floatingTextLabel.mainContainer).GetComponent<FastNativeScoreLabel>()?.Restore();
			}
		}
	}

	private static readonly HashSet<PlacementRoutine> pendingPlacementRoutines = new HashSet<PlacementRoutine>();

	public const string PluginGuid = "slipskid.fastintermissions";

	public const string PluginName = "Slip & Skid - Fast Intermissions";

	public const string PluginVersion = "0.1.4";

	internal const float ScoreSpeed = 2f;

	internal const float IntermissionSpeed = 2.5f;

	internal const float TransitionSpeed = 2f;

	internal const float FinalResultsDuration = 12f;

	private static readonly ConstructorInfo WaitForSecondsConstructor = AccessTools.Constructor(typeof(WaitForSeconds), new Type[1] { typeof(float) }, false);

	private static readonly MethodInfo ScoreDelayScaler = AccessTools.Method(typeof(FastIntermissionsPlugin), "ScaleScoreDelay", (Type[])null, (Type[])null);

	private static readonly MethodInfo IntermissionDelayScaler = AccessTools.Method(typeof(FastIntermissionsPlugin), "ScaleIntermissionDelay", (Type[])null, (Type[])null);

	private static readonly MethodInfo PlacementWaitFactory = AccessTools.Method(typeof(FastIntermissionsPlugin), "WaitAfterPlacement", (Type[])null, (Type[])null);

	internal static FastIntermissionsPlugin Instance;

	private Harmony harmony;

	private static bool patchValidationFailed;

	private static MonoBehaviour secretPlacements;

	private static FieldInfo serverRevealPending;

	private static FieldInfo clientRevealPending;

	private static PropertyInfo secretRuleEnabled;

	private static bool preserveNativePlacementDelay;

	private static bool HasPendingPlacementRoutines()
	{
		pendingPlacementRoutines.RemoveWhere((PlacementRoutine work) => (Object)(object)work.owner == (Object)null || !((Component)work.owner).gameObject.activeInHierarchy);
		return pendingPlacementRoutines.Count != 0;
	}

	private static IEnumerator TrackPlacementRoutine(Obstacle owner, IEnumerator routine)
	{
		PlacementRoutine work = new PlacementRoutine
		{
			owner = owner
		};
		pendingPlacementRoutines.Add(work);
		try
		{
			while (routine.MoveNext())
			{
				yield return routine.Current;
			}
		}
		finally
		{
			pendingPlacementRoutines.Remove(work);
			(routine as IDisposable)?.Dispose();
		}
	}

	private void Awake()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		Instance = this;
		patchValidationFailed = false;
		InitializePlacementCompatibility();
		harmony = new Harmony("slipskid.fastintermissions");
		try
		{
			harmony.PatchAll(typeof(FastIntermissionsPlugin).Assembly);
			if (patchValidationFailed)
			{
				throw new InvalidOperationException("Une ou plusieurs séquences temporelles attendues n'ont pas été reconnues.");
			}
		}
		catch (Exception ex)
		{
			try
			{
				harmony.UnpatchSelf();
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Nettoyage des patchs incomplets impossible.\n" + ex2));
			}
			harmony = null;
			((BaseUnityPlugin)this).Logger.LogError((object)("Fast Intermissions désactivé : version du jeu incompatible ou patch incomplet.\n" + ex));
			return;
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Fast Intermissions 0.1.4 chargé : classement x" + 2f.ToString("0.##") + ", intermanches x" + 2.5f.ToString("0.##") + ", transitions x" + 2f.ToString("0.##") + "."));
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		harmony = null;
		Instance = null;
		secretPlacements = null;
		serverRevealPending = null;
		clientRevealPending = null;
		secretRuleEnabled = null;
		preserveNativePlacementDelay = false;
		pendingPlacementRoutines.Clear();
	}

	internal static float ScaleScoreDelay(float duration)
	{
		return ScaleDuration(duration, 2f);
	}

	internal static float ScaleIntermissionDelay(float duration)
	{
		return ScaleDuration(duration, 2.5f);
	}

	private static float ScaleTransitionDelay(float duration)
	{
		return ScaleDuration(duration, 2f);
	}

	private static float ScaleDuration(float duration, float multiplier)
	{
		if (duration <= 0f || multiplier <= 1f)
		{
			return duration;
		}
		return Math.Min(duration, Math.Max(0.02f, duration / multiplier));
	}

	private static void InitializePlacementCompatibility()
	{
		secretPlacements = null;
		serverRevealPending = null;
		clientRevealPending = null;
		secretRuleEnabled = null;
		preserveNativePlacementDelay = false;
		Type type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
			select assembly.GetType("SlipSkid.SecretPlacements.SecretPlacementsPlugin", throwOnError: false)).FirstOrDefault((Type candidate) => candidate != null);
		if (type == null)
		{
			return;
		}
		preserveNativePlacementDelay = true;
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(type, "Instance");
			secretPlacements = (MonoBehaviour)((fieldInfo == null) ? null : /*isinst with value type is only supported in some contexts*/);
			serverRevealPending = AccessTools.Field(type, "_barrierActive");
			clientRevealPending = AccessTools.Field(type, "_clientBarrierActive");
			secretRuleEnabled = AccessTools.Property(type, "RuleEnabled");
			if ((Object)(object)secretPlacements != (Object)null && serverRevealPending != null && clientRevealPending != null && secretRuleEnabled != null && secretRuleEnabled.PropertyType == typeof(bool) && serverRevealPending.FieldType == typeof(bool) && clientRevealPending.FieldType == typeof(bool))
			{
				preserveNativePlacementDelay = false;
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Secret Placements : attente de la finalisation avant la phase suivante.");
				return;
			}
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Adaptation Secret Placements indisponible : " + ex.Message));
		}
		((BaseUnityPlugin)Instance).Logger.LogWarning((object)"Secret Placements non reconnu : pause native après placement conservée, sans accélération.");
	}

	internal static IEnumerator WaitAfterPlacement(float duration)
	{
		yield return (object)new WaitForSeconds(duration);
		while (HasPendingPlacementRoutines() || (!preserveNativePlacementDelay && (Object)(object)secretPlacements != (Object)null && ((Behaviour)secretPlacements).isActiveAndEnabled && (bool)secretRuleEnabled.GetValue(secretPlacements, null) && ((bool)serverRevealPending.GetValue(secretPlacements) || (bool)clientRevealPending.GetValue(secretPlacements))))
		{
			yield return null;
		}
	}

	private static MethodBase FindStateMachineMoveNext(Type parent, string routineName)
	{
		if (parent == null)
		{
			return null;
		}
		Type type = parent.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((Type type2) => type2.Name.Contains("<" + routineName + ">"));
		return (type == null) ? null : AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null);
	}

	private static bool Calls(CodeInstruction instruction, MethodBase method)
	{
		return method != null && instruction != null && object.Equals(instruction.operand, method);
	}

	private static IEnumerable<CodeInstruction> ScaleWaits(IEnumerable<CodeInstruction> instructions, MethodInfo scaler, string patchName, int expectedWaits)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		List<CodeInstruction> list = instructions.ToList();
		int num = 0;
		for (int i = 0; i < list.Count; i++)
		{
			if (Calls(list[i], WaitForSecondsConstructor))
			{
				CodeInstruction val = new CodeInstruction(OpCodes.Call, (object)scaler);
				val.labels.AddRange(list[i].labels);
				list[i].labels.Clear();
				val.blocks.AddRange(list[i].blocks);
				list[i].blocks.Clear();
				list.Insert(i, val);
				num++;
				i++;
			}
		}
		LogPatchResult(patchName, num, expectedWaits);
		return list;
	}

	private static IEnumerable<CodeInstruction> ScaleScoreBoardRoutine(IEnumerable<CodeInstruction> instructions)
	{
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Expected O, but got Unknown
		List<CodeInstruction> list = instructions.ToList();
		MethodInfo method = AccessTools.Method(typeof(FloatingTextLabelGenerator), "Generate", (Type[])null, (Type[])null);
		List<int> list2 = new List<int>();
		for (int i = 0; i < list.Count; i++)
		{
			if (!Calls(list[i], method))
			{
				continue;
			}
			int num = Math.Max(0, i - 16);
			for (int j = num; j < i; j++)
			{
				if (!(list[j].opcode != OpCodes.Ldc_R4) && list[j].operand is float num2 && (!(Math.Abs(num2 - 0.3f) > 0.0001f) || !(Math.Abs(num2 - 3f) > 0.0001f)))
				{
					list2.Add(j);
				}
			}
		}
		foreach (int item in from value in list2.Distinct()
			orderby value descending
			select value)
		{
			list.Insert(item + 1, new CodeInstruction(OpCodes.Call, (object)ScoreDelayScaler));
		}
		LogPatchResult("Durées des libellés de points", list2.Distinct().Count(), 4);
		return ScaleWaits(list, ScoreDelayScaler, "Pauses du décompte des points", 13);
	}

	private static void ScaleFloatArgument(object[] arguments, int index, Func<float, float> scaler)
	{
		if (arguments != null && index >= 0 && index < arguments.Length)
		{
			object obj = arguments[index];
			float arg = default(float);
			int num;
			if (obj is float)
			{
				arg = (float)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			if (num != 0)
			{
				arguments[index] = scaler(arg);
			}
		}
	}

	private static void LogPatchResult(string patchName, int replacements, int expected)
	{
		string text = patchName + " : " + replacements + " temporisation(s) trouvée(s), " + expected + " attendue(s).";
		if (replacements == expected)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)text);
			return;
		}
		patchValidationFailed = true;
		((BaseUnityPlugin)Instance).Logger.LogError((object)text);
	}
}
internal sealed class FastNativeScoreLayout : MonoBehaviour
{
	internal bool longSequence;

	private PlayerScoreElement row;

	private int peakCount;

	private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4];

	internal void Bind(PlayerScoreElement value)
	{
		row = value;
		VerticalLayoutGroup component = ((Component)row.labelsHolder).GetComponent<VerticalLayoutGroup>();
		if ((Object)(object)component != (Object)null)
		{
			((HorizontalOrVerticalLayoutGroup)component).spacing = 6f;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((LayoutGroup)component).childAlignment = (TextAnchor)4;
		}
		Refresh();
	}

	private void LateUpdate()
	{
		Refresh();
	}

	internal void Refresh()
	{
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)row == (Object)null)
		{
			return;
		}
		RectTransform labelsHolder = row.labelsHolder;
		Transform parent = ((Transform)labelsHolder).parent;
		if ((Object)(object)row.checkPointIndicatorsHolder != (Object)null && (Object)(object)parent != (Object)null)
		{
			row.checkPointIndicatorsHolder.GetWorldCorners(corners);
			float num = corners.Max((Vector3 point) => parent.InverseTransformPoint(point).y);
			labelsHolder.GetWorldCorners(corners);
			float num2 = corners.Min((Vector3 point) => parent.InverseTransformPoint(point).y);
			float num3 = num + 12f - num2;
			if (num3 > 0.1f)
			{
				labelsHolder.offsetMin += new Vector2(0f, num3);
			}
		}
		FastNativeScoreLabel[] array = (from state in ((Component)this).GetComponentsInChildren<FastNativeScoreLabel>()
			where state.bound && (Object)(object)((Component)state).transform.parent == (Object)(object)((Component)this).transform && ((Component)state).gameObject.activeInHierarchy
			select state).ToArray();
		if (array.Length == 0)
		{
			peakCount = 0;
			return;
		}
		peakCount = Mathf.Max(peakCount, array.Length);
		Rect rect = labelsHolder.rect;
		float height = Mathf.Clamp((((Rect)(ref rect)).height - 6f * (float)(peakCount - 1)) / (float)peakCount, 20f, 60f);
		bool flag = false;
		FastNativeScoreLabel[] array2 = array;
		foreach (FastNativeScoreLabel fastNativeScoreLabel in array2)
		{
			flag |= fastNativeScoreLabel.Fit(height);
		}
		if (flag)
		{
			LayoutRebuilder.ForceRebuildLayoutImmediate(labelsHolder);
		}
	}
}
internal sealed class FastNativeScoreLabel : MonoBehaviour
{
	private struct RectSnapshot
	{
		internal RectTransform rect;

		internal Vector2 anchorMin;

		internal Vector2 anchorMax;

		internal Vector2 offsetMin;

		internal Vector2 offsetMax;
	}

	internal bool bound;

	private FloatingTextLabel label;

	private LayoutElement layout;

	private float minHeight;

	private float preferredHeight;

	private float flexibleHeight;

	private float fontSize;

	private float fontMin;

	private float fontMax;

	private bool autoSize;

	private readonly List<RectSnapshot> rects = new List<RectSnapshot>();

	internal void Bind(FloatingTextLabel value)
	{
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: 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_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		if (bound)
		{
			Restore();
		}
		label = value;
		layout = ((Component)this).GetComponent<LayoutElement>();
		if ((Object)(object)layout == (Object)null)
		{
			layout = ((Component)this).gameObject.AddComponent<LayoutElement>();
		}
		minHeight = layout.minHeight;
		preferredHeight = layout.preferredHeight;
		flexibleHeight = layout.flexibleHeight;
		TMP_Text val = label.label;
		fontSize = val.fontSize;
		fontMin = val.fontSizeMin;
		fontMax = val.fontSizeMax;
		autoSize = val.enableAutoSizing;
		RectTransform[] componentsInChildren = ((Component)label.mainContainer).GetComponentsInChildren<RectTransform>(true);
		foreach (RectTransform val2 in componentsInChildren)
		{
			if (!((Object)(object)val2 == (Object)(object)label.mainContainer))
			{
				rects.Add(new RectSnapshot
				{
					rect = val2,
					anchorMin = val2.anchorMin,
					anchorMax = val2.anchorMax,
					offsetMin = val2.offsetMin,
					offsetMax = val2.offsetMax
				});
				val2.anchorMin = Vector2.zero;
				val2.anchorMax = Vector2.one;
				val2.offsetMin = (Vector2)(((Object)(object)val2 == (Object)(object)val.rectTransform) ? new Vector2(8f, 0f) : Vector2.zero);
				val2.offsetMax = (Vector2)(((Object)(object)val2 == (Object)(object)val.rectTransform) ? new Vector2(-8f, 0f) : Vector2.zero);
			}
		}
		val.enableAutoSizing = true;
		val.fontSizeMin = 16f;
		bound = true;
	}

	internal bool Fit(float height)
	{
		float num = Mathf.Clamp(height - 8f, 16f, 34f);
		bool result = Mathf.Abs(layout.preferredHeight - height) > 0.1f || Mathf.Abs(label.label.fontSizeMax - num) > 0.1f;
		layout.minHeight = height;
		layout.preferredHeight = height;
		layout.flexibleHeight = 0f;
		label.label.fontSizeMax = num;
		return result;
	}

	internal void Restore()
	{
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		if (!bound || (Object)(object)label == (Object)null)
		{
			return;
		}
		layout.minHeight = minHeight;
		layout.preferredHeight = preferredHeight;
		layout.flexibleHeight = flexibleHeight;
		label.label.enableAutoSizing = autoSize;
		label.label.fontSizeMin = fontMin;
		label.label.fontSizeMax = fontMax;
		label.label.fontSize = fontSize;
		foreach (RectSnapshot rect in rects)
		{
			if (!((Object)(object)rect.rect == (Object)null))
			{
				rect.rect.anchorMin = rect.anchorMin;
				rect.rect.anchorMax = rect.anchorMax;
				rect.rect.offsetMin = rect.offsetMin;
				rect.rect.offsetMax = rect.offsetMax;
			}
		}
		rects.Clear();
		bound = false;
	}
}