Decompiled source of FTK MultiMax Rework v2 v2.1.0

FTK MultiMax Rework v2.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using FTK_MultiMax_Rework_v2.PatchHelpers;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Rewired;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("FTK MultiMax Rework v2")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Polars Bear (upon work by justedm & samupo)")]
[assembly: AssemblyProduct("FTK MultiMax Rework v2")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("93679fb8-d7d5-4e0d-841d-239d6bd70317")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyVersion("2.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace FTK_MultiMax_Rework_v2
{
	public static class ConfigHandler
	{
		public static ConfigEntry<int> MaxPlayersConfig { get; private set; }

		public static void InitializeConfig()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "MultiMaxRework.cfg");
			ConfigFile val = new ConfigFile(text, true);
			MaxPlayersConfig = val.Bind<int>("General", "MaxPlayers", 5, "The max number of players");
			if (!File.Exists(text))
			{
				val.Save();
			}
		}

		public static void InitializeMaxPlayers()
		{
			if (MaxPlayersConfig != null)
			{
				GameFlowMC.gMaxPlayers = MaxPlayersConfig.Value;
				GameFlowMC.gMaxEnemies = GameFlowMC.gMaxPlayers;
				uiQuickPlayerCreate.Default_Classes = new int[GameFlowMC.gMaxPlayers];
			}
			else
			{
				Debug.LogError((object)"maxPlayersConfig is not initialized!");
			}
		}
	}
	public class DummiesHandler
	{
		public static void CreateDummies()
		{
			Main.Log("Making Dummies");
			List<GameObject> list = new List<GameObject>();
			for (int i = 0; i < Mathf.Max(3, GameFlowMC.gMaxPlayers); i++)
			{
				if (i < 3)
				{
					list.Add(FTKHub.Instance.m_Dummies[i]);
					continue;
				}
				GameObject val = Object.Instantiate<GameObject>(FTKHub.Instance.m_Dummies[2], FTKHub.Instance.m_Dummies[2].transform.parent);
				((Object)val).name = "Player " + (i + 1) + " Dummy";
				val.GetComponent<PhotonView>().viewID = 3245 + i;
				list.Add(val);
			}
			for (int j = 0; j < Mathf.Max(3, GameFlowMC.gMaxEnemies); j++)
			{
				if (j < 3)
				{
					list.Add(FTKHub.Instance.m_Dummies[j + 3]);
					continue;
				}
				GameObject val2 = Object.Instantiate<GameObject>(FTKHub.Instance.m_Dummies[5], FTKHub.Instance.m_Dummies[5].transform.parent);
				((Object)val2).name = "Enemy " + (j + 1) + " Dummy";
				val2.GetComponent<PhotonView>().viewID = 3045 + j;
				list.Add(val2);
			}
			FTKHub.Instance.m_Dummies = list.ToArray();
			Main.Log("Dummies created");
		}

		public static GameObject CreateDummy(GameObject[] source, int index, string prefix)
		{
			GameObject val;
			if (index < 3)
			{
				val = source[index];
			}
			else
			{
				val = Object.Instantiate<GameObject>(source[2], source[2].transform.parent);
				((Object)val).name = $"{prefix} {index + 1} Dummy";
				val.GetComponent<PhotonView>().viewID = 3245 + index;
			}
			return val;
		}
	}
	public static class TargetPositions
	{
		public static void Fix(Transform root)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			int gMaxPlayers = GameFlowMC.gMaxPlayers;
			GameObject gameObject = ((Component)root.Find("Player 2_target")).gameObject;
			GameObject gameObject2 = ((Component)root.Find("Player 3_target")).gameObject;
			Vector3 localPosition = gameObject.transform.localPosition;
			Vector3 val = gameObject2.transform.localPosition - localPosition;
			Vector3 val2 = val * (float)gMaxPlayers / 3f;
			Vector3 val3 = (val2 - val) * -0.5f;
			int siblingIndex = gameObject.transform.GetSiblingIndex();
			for (int i = 0; i < gMaxPlayers; i++)
			{
				Transform val4 = root.Find($"Player {i + 1}_target");
				if (!Object.op_Implicit((Object)(object)val4))
				{
					GameObject obj = Object.Instantiate<GameObject>(gameObject2, root);
					((Object)obj).name = $"Player {i + 1}_target";
					val4 = obj.transform;
					val4.SetSiblingIndex(siblingIndex + i);
				}
				else if (i == 0)
				{
					val4.SetSiblingIndex(siblingIndex + 1);
				}
				float num = (float)i / (float)(gMaxPlayers - 1);
				val4.localPosition = localPosition + val2 * num + val3;
			}
		}
	}
	public static class RoomHandler
	{
		public static bool CreateRoom(ref GameLogic __instance, string _roomName, bool _isOpen)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			PhotonNetwork.offlineMode = false;
			RoomOptions val = new RoomOptions();
			TypedLobby val2 = new TypedLobby();
			val.IsOpen = _isOpen;
			val.IsVisible = _isOpen;
			if ((int)__instance.m_GameMode == 0)
			{
				val.MaxPlayers = 1;
			}
			else
			{
				val.MaxPlayers = (byte)GameFlowMC.gMaxPlayers;
			}
			val2.Type = (LobbyType)0;
			PhotonNetwork.CreateRoom(_roomName, val, val2);
			return false;
		}
	}
	[BepInPlugin("polarsbear.ftk.multimaxrework.patched", "MultiMaxReworkV2", "2.0")]
	public class Main : BaseUnityPlugin
	{
		private const string pluginGuid = "polarsbear.ftk.multimaxrework.patched";

		private const string pluginName = "MultiMaxReworkV2";

		private const string pluginVersion = "2.0";

		public static Harmony Harmony { get; } = new Harmony("polarsbear.ftk.multimaxrework.patched");


		public static void Log(object message)
		{
			Debug.Log((object)string.Format("[{0}]: {1}", "MultiMaxReworkV2", message));
		}

		public IEnumerator Start()
		{
			Log("Initializing...");
			ConfigHandler.InitializeConfig();
			ConfigHandler.InitializeMaxPlayers();
			Log("Finished initializing");
			Log("Patching...");
			PatchMethods();
			Log("Finished patching");
			Log("Reshaping player creation gui array");
			typeof(uiQuickPlayerCreate).GetField("guiQuickPlayerCreates", BindingFlags.Static | BindingFlags.NonPublic)?.SetValue(null, new uiQuickPlayerCreate[GameFlowMC.gMaxPlayers]);
			uiQuickPlayerCreate.Default_Classes = new int[GameFlowMC.gMaxPlayers];
			Log("Waiting for game to load...");
			while (!Object.op_Implicit((Object)(object)FTKHub.Instance))
			{
				yield return null;
			}
			Log("Startup done");
		}

		private void PatchMethods()
		{
			Type[] typesWithAttribute = Assembly.GetExecutingAssembly().GetTypesWithAttribute<PatchType>();
			for (int i = 0; i < typesWithAttribute.Length; i++)
			{
				PatchUtils.PatchClass(typesWithAttribute[i]);
			}
		}
	}
}
namespace FTK_MultiMax_Rework_v2.PatchHelpers
{
	public class PatchMethod : Attribute
	{
		public string methodName;

		public PatchMethod(string methodName)
		{
			this.methodName = methodName;
		}
	}
	public class PatchParams : Attribute
	{
		public Type[] parameters;

		public PatchParams(params Type[] parameters)
		{
			this.parameters = parameters;
		}
	}
	public class PatchPosition : Attribute
	{
		public PatchPositions position;

		public PatchPosition(PatchPositions position)
		{
			this.position = position;
		}
	}
	public enum PatchPositions
	{
		Prefix,
		Postfix,
		Transpiler,
		Finalizer,
		ILManipulator
	}
	public class PatchType : Attribute
	{
		public Type type;

		public PatchType(Type type)
		{
			this.type = type;
		}
	}
	public static class PatchUtils
	{
		private static void PatchMethod(Type target, PatchData data)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(target, data.patchedMethodName, data.parameters, (Type[])null);
			HarmonyMethod val = new HarmonyMethod(data.patchMethod);
			Main.Harmony.Patch((MethodBase)methodInfo, (data.position == PatchPositions.Prefix) ? val : null, (data.position == PatchPositions.Postfix) ? val : null, (data.position == PatchPositions.Transpiler) ? val : null, (data.position == PatchPositions.Finalizer) ? val : null, (data.position == PatchPositions.ILManipulator) ? val : null);
		}

		private static bool TryGetAttribute<AttrType>(this Type type, out AttrType attribute) where AttrType : Attribute
		{
			AttrType[] array = (AttrType[])type.GetCustomAttributes(typeof(AttrType), inherit: false);
			if (array.Length != 0)
			{
				attribute = array.First();
				return true;
			}
			attribute = null;
			return false;
		}

		private static AttrType? GetAttribute<AttrType>(this Type type) where AttrType : Attribute
		{
			if (!type.TryGetAttribute<AttrType>(out var attribute))
			{
				return null;
			}
			return attribute;
		}

		private static bool TryGetAttribute<AttrType>(this MethodInfo method, out AttrType attribute) where AttrType : Attribute
		{
			AttrType[] array = (AttrType[])method.GetCustomAttributes(typeof(AttrType), inherit: false);
			if (array.Length != 0)
			{
				attribute = array.First();
				return true;
			}
			attribute = null;
			return false;
		}

		private static AttrType? GetAttribute<AttrType>(this MethodInfo method) where AttrType : Attribute
		{
			if (!method.TryGetAttribute<AttrType>(out var attribute))
			{
				return null;
			}
			return attribute;
		}

		public static Type[] GetTypesWithAttribute<AttrType>(this Assembly assembly) where AttrType : Attribute
		{
			AttrType attribute;
			return (from type in assembly.GetTypes()
				where type.TryGetAttribute<AttrType>(out attribute)
				select type).ToArray();
		}

		private static List<PatchData> GetPatchMethods(this Type type)
		{
			MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
			List<PatchData> list = new List<PatchData>();
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo in array)
			{
				if (methodInfo.TryGetAttribute<PatchMethod>(out var attribute))
				{
					PatchParams attribute2 = methodInfo.GetAttribute<PatchParams>();
					PatchPositions position = PatchPositions.Prefix;
					if (methodInfo.TryGetAttribute<PatchPosition>(out var attribute3))
					{
						position = attribute3.position;
					}
					list.Add(new PatchData(attribute.methodName, position, methodInfo, attribute2?.parameters));
				}
			}
			return list;
		}

		public static void PatchClass(Type type)
		{
			Type type2 = type.GetAttribute<PatchType>().type;
			Main.Log("Patching class " + type2.Name + " with " + type.Name);
			foreach (PatchData patchMethod in type.GetPatchMethods())
			{
				PatchMethod(type2, patchMethod);
				Main.Log("    Patched method " + patchMethod.patchedMethodName + " with " + patchMethod.patchMethod.Name);
			}
		}
	}
	internal struct PatchData
	{
		public string patchedMethodName;

		public MethodInfo patchMethod;

		public Type[]? parameters;

		public PatchPositions position;

		public PatchData(string patchedMethodName, PatchPositions position, MethodInfo patchMethod, Type[]? parameters)
		{
			this.patchedMethodName = patchedMethodName;
			this.patchMethod = patchMethod;
			this.parameters = parameters;
			this.position = position;
		}
	}
}
namespace FTK_MultiMax_Rework_v2.Patches
{
	[PatchType(typeof(SceneDiorama))]
	public class SceneDioramaPatches
	{
		[PatchMethod("Awake")]
		[PatchPosition(PatchPositions.Postfix)]
		public static void FixDummyPositions(SceneDiorama __instance)
		{
			Diorama[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Diorama>();
			foreach (Diorama val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					FixDiorama(val);
				}
			}
		}

		private static void FixDiorama(Diorama diorama)
		{
			Main.Log("Fixing dummy positions for " + ((Object)diorama).name);
			foreach (Layout value in diorama.m_LayoutTable.Values)
			{
				TargetPositions.Fix(value.m_TargetRoot);
			}
		}
	}
	[PatchType(typeof(Diorama))]
	public class DioramaPatches
	{
		[PatchMethod("_resetTargetQueue")]
		[PatchPosition(PatchPositions.Prefix)]
		public static void DummySlide()
		{
			DummyAttackSlide[] array = Object.FindObjectsOfType<DummyAttackSlide>();
			foreach (DummyAttackSlide val in array)
			{
				if (val.m_Distances.Length < 1000)
				{
					float[] array2 = new float[1000];
					Array.Copy(val.m_Distances, array2, val.m_Distances.Length);
					val.m_Distances = array2;
					Main.Log(val.m_Distances);
				}
			}
		}

		[PatchMethod("SetupTargets")]
		[PatchPosition(PatchPositions.Postfix)]
		public static void SortTargets(ref List<Transform> _targetList)
		{
			for (int i = 0; i < GameFlowMC.gMaxPlayers; i++)
			{
				for (int j = 0; j < _targetList.Count - 1; j++)
				{
					Transform val = _targetList[j];
					if (!((Object)val).name.Contains("Player "))
					{
						continue;
					}
					Transform val2 = _targetList[j + 1];
					if (((Object)val2).name.Contains("Player "))
					{
						int num = int.Parse(Regex.Match(((Object)val).name, "\\d+").Value);
						int num2 = int.Parse(Regex.Match(((Object)val2).name, "\\d+").Value);
						if (num > num2)
						{
							_targetList[j] = val2;
							_targetList[j + 1] = val;
						}
					}
				}
			}
		}
	}
	[PatchType(typeof(EncounterSession))]
	public class EncounterSessionPatches
	{
		[PatchMethod("GiveOutLootXPGold")]
		[PatchPosition(PatchPositions.Prefix)]
		public static void XPModifierPatch(ref FTKPlayerID _recvPlayer, ref int _xp, ref int _gold)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			CharacterOverworld characterOverworldByFID = FTKHub.Instance.GetCharacterOverworldByFID(_recvPlayer);
			float xpModifier = characterOverworldByFID.m_CharacterStats.XpModifier;
			float goldModifier = characterOverworldByFID.m_CharacterStats.GoldModifier;
			if (GameFlowMC.gMaxPlayers > 3)
			{
				_xp = Mathf.RoundToInt((float)((double)((float)_xp * xpModifier) * 1.5));
				_gold = Mathf.RoundToInt((float)((double)((float)_gold * goldModifier) * 1.5));
			}
		}
	}
	[PatchType(typeof(PlayerHelper))]
	public class PlayerHelperPatches
	{
		[PatchMethod("GetPlayer")]
		[PatchPosition(PatchPositions.Prefix)]
		[PatchParams(new Type[] { typeof(int) })]
		public static bool FixRewire(int playerId, ref Player __result)
		{
			if (playerId < ReInput.players.playerCount)
			{
				return true;
			}
			__result = ReInput.players.GetPlayer(2);
			return false;
		}
	}
	[PatchType(typeof(uiCharacterCreateRoot))]
	public class uiCharacterCreateRootPatches
	{
		[PatchMethod("Start")]
		[PatchPosition(PatchPositions.Prefix)]
		public static void AddMorePlayerSlotsInMenu(ref uiCharacterCreateRoot __instance)
		{
			//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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			Main.Log(__instance);
			Main.Log(__instance.m_CreateUITargets);
			Main.Log(SelectScreenCamera.Instance.m_PlayerTargets.Length);
			if (__instance.m_CreateUITargets.Length < GameFlowMC.gMaxPlayers)
			{
				Transform[] array = (Transform[])(object)new Transform[GameFlowMC.gMaxPlayers];
				Transform[] array2 = (Transform[])(object)new Transform[GameFlowMC.gMaxPlayers];
				Vector3 position = SelectScreenCamera.Instance.m_PlayerTargets[0].position;
				Vector3 position2 = SelectScreenCamera.Instance.m_PlayerTargets[2].position;
				for (int i = 0; i < GameFlowMC.gMaxPlayers; i++)
				{
					if (i < __instance.m_CreateUITargets.Length)
					{
						array[i] = __instance.m_CreateUITargets[i];
						array2[i] = SelectScreenCamera.Instance.m_PlayerTargets[i];
					}
					else
					{
						array[i] = Object.Instantiate<Transform>(array[i - 1], array[i - 1].parent);
						array2[i] = Object.Instantiate<Transform>(array2[i - 1], array2[i - 1].parent);
					}
				}
				__instance.m_CreateUITargets = array;
				SelectScreenCamera.Instance.m_PlayerTargets = array2;
				for (int j = 0; j < __instance.m_CreateUITargets.Length; j++)
				{
					((Component)__instance.m_CreateUITargets[j]).GetComponent<RectTransform>().anchoredPosition = new Vector2(Mathf.Lerp(-550f, 550f, (float)j / (float)(__instance.m_CreateUITargets.Length - 1)), 129f);
				}
				for (int k = 0; k < SelectScreenCamera.Instance.m_PlayerTargets.Length; k++)
				{
					SelectScreenCamera.Instance.m_PlayerTargets[k].position = Vector3.Lerp(position, position2, (float)k / (float)(SelectScreenCamera.Instance.m_PlayerTargets.Length - 1));
				}
			}
			Main.Log("Slot Count: " + __instance.m_CreateUITargets.Length);
		}
	}
	[PatchType(typeof(uiGoldMenu))]
	public class uiGoldMenuPatches
	{
		[PatchMethod("Awake")]
		[PatchPosition(PatchPositions.Prefix)]
		public static bool GoldAwake(uiGoldMenu __instance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			Traverse val = Traverse.Create((object)__instance).Field("m_GoldEntries");
			__instance.m_InputFocus = ((Component)__instance).gameObject.GetComponent<FTKInputFocus>();
			__instance.m_InputFocus.m_InputMode = (InputMode)3;
			__instance.m_InputFocus.m_Cancel = new OnCancel(__instance.OnButtonCancel);
			if (val.GetValue() != null)
			{
				int num = GameFlowMC.gMaxPlayers - 2;
				val.GetValue<List<uiGoldMenuEntry>>().Add(__instance.m_FirstEntry);
				for (int i = 0; i < num; i++)
				{
					uiGoldMenuEntry item = Object.Instantiate<uiGoldMenuEntry>(__instance.m_FirstEntry, ((Component)__instance.m_FirstEntry).transform.parent, false);
					val.GetValue<List<uiGoldMenuEntry>>().Add(item);
				}
			}
			return false;
		}
	}
	[PatchType(typeof(uiHudScroller))]
	public class uiHudScrollerPatches
	{
		[PatchMethod("Init")]
		[PatchPosition(PatchPositions.Prefix)]
		public static bool InitHUD(ref uiHudScroller __instance, uiPlayerMainHud _playerHud, ref int ___m_Index, ref Dictionary<uiPlayerMainHud, int> ___m_TargetIndex, ref List<uiPlayerMainHud> ___m_Huds, ref float ___m_HudWidth, ref float[] ___m_Positions)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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)
			CharacterOverworld cow = _playerHud.m_Cow;
			int num;
			if (GameLogic.Instance.IsSinglePlayer())
			{
				num = ((FTKPlayerID)(ref cow.m_FTKPlayerID)).TurnIndex + 1;
				___m_Index = 0;
			}
			else
			{
				num = ((FTKPlayerID)(ref cow.m_FTKPlayerID)).TurnIndex + 1;
				___m_Index = ((FTKPlayerID)(ref cow.m_FTKPlayerID)).TurnIndex;
			}
			___m_TargetIndex[_playerHud] = num;
			___m_Huds.Add(_playerHud);
			RectTransform component = ((Component)_playerHud).GetComponent<RectTransform>();
			Rect rect = component.rect;
			___m_HudWidth = ((Rect)(ref rect)).width;
			Vector3 localPosition = ((Transform)component).localPosition;
			localPosition.y = 0f - component.anchoredPosition.y;
			if (num >= ___m_Positions.Length)
			{
				float[] array = new float[num + 1];
				Array.Copy(___m_Positions, array, ___m_Positions.Length);
				___m_Positions = array;
			}
			localPosition.x = ___m_Positions[num];
			((Transform)component).localPosition = localPosition;
			return false;
		}
	}
	[PatchType(typeof(uiPlayerMainHud))]
	public class uiPlayerMainHudPatches
	{
		[PatchMethod("Update")]
		[PatchPosition(PatchPositions.Prefix)]
		public static void PlaceUI(ref uiPlayerMainHud __instance)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			int turnIndex = ((FTKPlayerID)(ref __instance.m_Cow.m_FTKPlayerID)).TurnIndex;
			int gMaxPlayers = GameFlowMC.gMaxPlayers;
			float num = 725f;
			float num2 = 2f * num;
			RectTransform component = ((Component)__instance).GetComponent<RectTransform>();
			Rect rect = component.rect;
			float num3 = ((Rect)(ref rect)).width - 220f;
			float num4 = num2 / (float)gMaxPlayers;
			float num5 = Mathf.Min(1f, num4 / num3);
			component.anchoredPosition = new Vector2(Mathf.Lerp(0f - num, num, (float)turnIndex / (float)(gMaxPlayers - 1)), component.anchoredPosition.y);
			((Transform)component).localScale = new Vector3(num5, num5, num5);
		}
	}
	[PatchType(typeof(uiPopupMenu))]
	public class uiPopupMenuPatches
	{
		[PatchMethod("Awake")]
		[PatchPosition(PatchPositions.Prefix)]
		public static void PopupAwake(uiPopupMenu __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance) && __instance.m_Popups != null)
			{
				PopupButton val = ((IEnumerable<PopupButton>)__instance.m_Popups).FirstOrDefault((Func<PopupButton, bool>)((PopupButton popup) => (int)popup.m_Action == 6));
				if (val != null)
				{
					val.m_Count = GameFlowMC.gMaxPlayers - 1;
				}
			}
		}
	}
	[PatchType(typeof(uiPortraitHolderManager))]
	public class uiPortraitHolderManagerPatches
	{
		[PatchMethod("Create")]
		[PatchPosition(PatchPositions.Postfix)]
		[PatchParams(new Type[] { typeof(HexLand) })]
		public static void AddMorePlayersToUI(ref uiPortraitHolder __result)
		{
			int count = __result.m_PortraitActionPoints.Count;
			for (int i = count; i < GameFlowMC.gMaxPlayers; i++)
			{
				uiPortraitActionPoint item = Object.Instantiate<uiPortraitActionPoint>(__result.m_PortraitActionPoints[count - 1], ((Component)__result.m_PortraitActionPoints[count - 1]).transform.parent);
				__result.m_PortraitActionPoints.Add(item);
			}
		}
	}
	[PatchType(typeof(uiPortraitHolder))]
	public class uiPortraitHolderPatches
	{
		[PatchMethod("UpdateDisplay")]
		[PatchPosition(PatchPositions.Prefix)]
		public static bool UpdateDisplayPatch(uiPortraitHolder __instance, ref bool __result)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			if (__instance.m_PortraitActionPoints != null)
			{
				FieldInfo? field = typeof(uiPortraitHolder).GetField("m_FollowCarrier", BindingFlags.Instance | BindingFlags.NonPublic);
				FieldInfo field2 = typeof(uiPortraitHolder).GetField("m_CarrierPassengers", BindingFlags.Instance | BindingFlags.NonPublic);
				MiniHexInfo val = (MiniHexInfo)(field?.GetValue(__instance));
				List<CharacterOverworld> list = (List<CharacterOverworld>)(field2?.GetValue(__instance));
				if ((object)field == null && __instance.m_HexLand.m_PlayersInHex.Count == 0)
				{
					((Component)__instance).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)__instance).gameObject);
					return false;
				}
				((Component)__instance).gameObject.SetActive(true);
				__instance.m_PortraitAndName.Hide();
				((Component)__instance.m_PortraitRoot).gameObject.SetActive(true);
				foreach (uiPortraitActionPoint portraitActionPoint in __instance.m_PortraitActionPoints)
				{
					portraitActionPoint.ResetShouldShow();
				}
				if ((Object)(object)val != (Object)null)
				{
					int num = 0;
					foreach (CharacterOverworld item in list)
					{
						if (num < __instance.m_PortraitActionPoints.Count)
						{
							__instance.m_PortraitActionPoints[num].CalculateShouldShow(item, true);
						}
						num++;
					}
				}
				else
				{
					int num2 = 0;
					foreach (CharacterOverworld item2 in __instance.m_HexLand.m_PlayersInHex)
					{
						if (num2 < __instance.m_PortraitActionPoints.Count)
						{
							__instance.m_PortraitActionPoints[num2].CalculateShouldShow(item2, false);
						}
						num2++;
					}
				}
				foreach (uiPortraitActionPoint portraitActionPoint2 in __instance.m_PortraitActionPoints)
				{
					portraitActionPoint2.UpdateShow();
				}
			}
			__result = true;
			return false;
		}
	}
	[PatchType(typeof(uiStartGame))]
	public class uiStartGamePatches
	{
		[PatchMethod("StartGame")]
		[PatchPosition(PatchPositions.Prefix)]
		public static void RecreateDummies()
		{
			DummiesHandler.CreateDummies();
		}
	}
}