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 BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Rewired;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FTK-MultiMax-Rework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FTK-MultiMax-Rework")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("93679fb8-d7d5-4e0d-841d-239d6bd70317")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FTK_MultiMax_Rework;
public static class ConfigHandler
{
public static ConfigEntry<int> MaxPlayersConfig { get; private set; }
public static void InitializeConfig()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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 static class DummiesHandler
{
public static void CreateDummies()
{
Debug.Log((object)"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();
GameObject[] dummies = FTKHub.Instance.m_Dummies;
Debug.Log((object)"MultiMax - Done");
}
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 EncounterSessionPatches
{
public static void XPModifierPatch(ref FTKPlayerID _recvPlayer, ref int _xp, ref int _gold)
{
//IL_0007: 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));
}
}
}
public static class RoomHandler
{
public static bool CreateRoom(ref GameLogic __instance, string _roomName, bool _isOpen)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Expected O, but got Unknown
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Invalid comparison between Unknown and I4
//IL_004d: 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;
}
}
public class uiGoldMenuPatches
{
public static bool GoldAwake(uiGoldMenu __instance)
{
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: 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 val2 = Object.Instantiate<uiGoldMenuEntry>(__instance.m_FirstEntry);
((Component)val2).transform.SetParent(((Component)__instance.m_FirstEntry).transform.parent, false);
val.GetValue<List<uiGoldMenuEntry>>().Add(val2);
}
}
return false;
}
}
[BepInPlugin("fortheking.edm.multimaxrework", "MultiMaxRework", "1.4")]
public class Main : BaseUnityPlugin
{
private const string pluginGuid = "fortheking.edm.multimaxrework";
private const string pluginName = "MultiMaxRework";
private const string pluginVersion = "1.4";
private static Harmony Harmony { get; set; } = new Harmony("fortheking.edm.multimaxrework");
public IEnumerator Start()
{
Debug.Log((object)"MultiMax Rework - Initializing...");
ConfigHandler.InitializeConfig();
ConfigHandler.InitializeMaxPlayers();
Debug.Log((object)"MultiMax Rework - Patching...");
PatchMethods();
typeof(uiQuickPlayerCreate).GetField("guiQuickPlayerCreates", BindingFlags.Static | BindingFlags.NonPublic).SetValue(null, new uiQuickPlayerCreate[GameFlowMC.gMaxPlayers]);
uiQuickPlayerCreate.Default_Classes = new int[GameFlowMC.gMaxPlayers];
Harmony.Patch((MethodBase)AccessTools.Method(typeof(uiCharacterCreateRoot), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Main), "AddMorePlayerSlotsInMenu", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerHelper), "GetPlayer", new Type[1] { typeof(int) }, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(Main), "FixRewire", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Harmony.Patch((MethodBase)AccessTools.Method(typeof(uiPortraitHolderManager), "Create", new Type[1] { typeof(HexLand) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(Main), "AddMorePlayersToUI", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Harmony.Patch((MethodBase)AccessTools.Method(typeof(uiPortraitHolder), "UpdateDisplay", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(Main), "UpdateDisplayPatch", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Harmony.Patch((MethodBase)AccessTools.Method(typeof(uiPlayerMainHud), "Update", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(Main), "PlaceUI", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Harmony.Patch((MethodBase)AccessTools.Method(typeof(uiHudScroller), "Init", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(Main), "InitHUD", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Harmony.Patch((MethodBase)AccessTools.Method(typeof(Diorama), "_resetTargetQueue", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(Main), "DummySlide", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
while ((Object)(object)FTKHub.Instance == (Object)null)
{
yield return null;
}
DummiesHandler.CreateDummies();
Debug.Log((object)"MultiMax Rework - Done");
}
private void PatchMethods()
{
PatchMethod<uiGoldMenu>("Awake", typeof(uiGoldMenuPatches), "GoldAwake");
PatchMethod<uiPopupMenu>("Awake", typeof(uiPopupMenuPatches), "PopupAwake");
PatchMethod<EncounterSession>("GiveOutLootXPGold", typeof(EncounterSessionPatches), "XPModifierPatch");
}
private void PatchMethod<T>(string originalMethodName, Type patchClass, string patchMethodName, Type[] parameterTypes = null)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(T), originalMethodName, parameterTypes, (Type[])null);
MethodInfo methodInfo2 = AccessTools.Method(patchClass, patchMethodName, (Type[])null, (Type[])null);
Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
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_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_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
int num = 0;
CharacterOverworld cow = _playerHud.m_Cow;
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;
}
public static void PlaceUI(ref uiPlayerMainHud __instance)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: 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_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: 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 = 725f;
float num3 = num2 - num;
Rect rect = ((Component)__instance).GetComponent<RectTransform>().rect;
float num4 = ((Rect)(ref rect)).width - 220f;
float num5 = num3 / (float)gMaxPlayers;
float num6 = Mathf.Min(1f, num5 / num4);
((Component)__instance).GetComponent<RectTransform>().anchoredPosition = new Vector2(Mathf.Lerp(num, num2, (float)turnIndex / (float)(gMaxPlayers - 1)), ((Component)__instance).GetComponent<RectTransform>().anchoredPosition.y);
((Transform)((Component)__instance).GetComponent<RectTransform>()).localScale = new Vector3(num6, num6, num6);
}
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);
}
}
public static bool UpdateDisplayPatch(uiPortraitHolder __instance, ref bool __result)
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: 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;
}
public static bool FixRewire(int playerId, ref Player __result)
{
if (playerId < ReInput.players.playerCount)
{
return true;
}
__result = ReInput.players.GetPlayer(2);
return false;
}
public static void AddMorePlayerSlotsInMenu(ref uiCharacterCreateRoot __instance)
{
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Unknown result type (might be due to invalid IL or missing references)
//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
Debug.Log((object)("[MULTIMAX REWORK] : " + (object)__instance));
Debug.Log((object)("[MULTIMAX REWORK] : " + __instance.m_CreateUITargets));
Debug.Log((object)("[MULTIMAX REWORK] : " + 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));
}
}
Debug.Log((object)("[MULTIMAX REWORK] : SLOT COUNT " + __instance.m_CreateUITargets.Length));
}
public static void DummySlide()
{
DummyAttackSlide[] array = Object.FindObjectsOfType<DummyAttackSlide>();
DummyAttackSlide[] array2 = array;
foreach (DummyAttackSlide val in array2)
{
if (val.m_Distances.Length < 1000)
{
float[] array3 = new float[1000];
Array.Copy(val.m_Distances, array3, val.m_Distances.Length);
val.m_Distances = array3;
Debug.Log((object)val.m_Distances);
}
}
}
}
public static class uiPopupMenuPatches
{
public static void PopupAwake(uiPopupMenu __instance)
{
if (!((Object)(object)__instance == (Object)null) && __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;
}
}
}
}