using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using FMODUnity;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SuperFantasyKingdom;
using SuperFantasyKingdom.TitleScreen;
using SuperFantasyKingdom.UI;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("UnlimitedJail")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+14a22b142920a276e529c9edd73b255a4bf0cc56")]
[assembly: AssemblyProduct("Unlimited Jail")]
[assembly: AssemblyTitle("UnlimitedJail")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 UnlimitedJail
{
[BepInPlugin("ownly.unlimitedjail", "Unlimited Jail", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Log;
private void Awake()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID).PatchAll();
}
}
internal static class Filter
{
public static void Apply(UnlockedUnitsManager manager)
{
List<string> stashed = Stash.Units;
Traverse obj = Traverse.Create((object)manager);
List<string> value = obj.Field("m_UnlockedUnits").GetValue<List<string>>();
List<string> value2 = obj.Field("m_Banned").GetValue<List<string>>();
foreach (string item in stashed)
{
value.Remove(item);
if (!value2.Contains(item))
{
value2.Add(item);
}
}
value2.RemoveAll((string id) => id != "empty" && !stashed.Contains(id));
}
}
[HarmonyPatch(typeof(UnlockedUnitsManager), "Awake")]
internal static class Patch_UnlockedUnitsAwake
{
private static void Postfix(UnlockedUnitsManager __instance)
{
try
{
Filter.Apply(__instance);
}
catch
{
}
}
}
[HarmonyPatch(typeof(UnlockedUnitsManager), "SetBannedUnits")]
internal static class Patch_SetBannedUnits
{
private static void Postfix(UnlockedUnitsManager __instance)
{
try
{
Filter.Apply(__instance);
}
catch
{
}
}
}
internal static class Jail
{
internal const string Empty = "empty";
private static readonly HashSet<string> s_Warned = new HashSet<string>();
public static string Force(string jailed)
{
if (!string.IsNullOrEmpty(jailed) && jailed != "empty" && s_Warned.Add(jailed))
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("jail slot held " + jailed + " - the mod frees it, jail it from the selection screen to keep it held back"));
}
}
return "empty";
}
public static void Paint(TitleScreenJail jail, int index)
{
List<string> units = Stash.Units;
Traverse val = Traverse.Create((object)jail);
GameObject value = val.Field("jail" + index).GetValue<GameObject>();
GameObject value2 = val.Field("jail" + index + "Rubble").GetValue<GameObject>();
Image value3 = val.Field("jail" + index + "Door").GetValue<Image>();
ImageAnimator value4 = val.Field("jail" + index + "Jailed").GetValue<ImageAnimator>();
if (units.Count < index)
{
return;
}
Unit unit = AddressablesManager.Instance.GetUnit(units[index - 1]);
if ((Object)(object)unit == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)("stashed unit has no prefab: " + units[index - 1]));
}
}
else
{
value.SetActive(true);
value2.SetActive(false);
value3.sprite = val.Field("spriteDoorClosed").GetValue<Sprite>();
value4.SetSprites(((UnitBase)unit).GetIdleSprites());
((Component)value4).gameObject.SetActive(true);
}
}
}
[HarmonyPatch(typeof(RaceDataManager), "GetJail1")]
internal static class Patch_GetJail1
{
private static void Postfix(ref string __result)
{
__result = Jail.Force(__result);
}
}
[HarmonyPatch(typeof(RaceDataManager), "GetJail2")]
internal static class Patch_GetJail2
{
private static void Postfix(ref string __result)
{
__result = Jail.Force(__result);
}
}
[HarmonyPatch(typeof(RaceDataManager), "GetJail3")]
internal static class Patch_GetJail3
{
private static void Postfix(ref string __result)
{
__result = Jail.Force(__result);
}
}
[HarmonyPatch(typeof(TitleScreenJail), "ShowJail1")]
internal static class Patch_ShowJail1
{
private static void Postfix(TitleScreenJail __instance)
{
try
{
Jail.Paint(__instance, 1);
}
catch
{
}
}
}
[HarmonyPatch(typeof(TitleScreenJail), "ShowJail2")]
internal static class Patch_ShowJail2
{
private static void Postfix(TitleScreenJail __instance)
{
try
{
Jail.Paint(__instance, 2);
}
catch
{
}
}
}
[HarmonyPatch(typeof(TitleScreenJail), "ShowJail3")]
internal static class Patch_ShowJail3
{
private static void Postfix(TitleScreenJail __instance)
{
try
{
Jail.Paint(__instance, 3);
}
catch
{
}
}
}
[HarmonyPatch(typeof(TitleScreenJail), "SetJailed")]
internal static class Patch_SetJailed
{
private static bool Prefix(TitleScreenJail __instance)
{
try
{
Traverse val = Traverse.Create((object)__instance);
int value = val.Field("m_SelectedCell").GetValue<int>();
if (value >= 1 && value <= 3)
{
Button value2 = val.Field("jail" + value + "Button").GetValue<Button>();
if ((Object)(object)value2 != (Object)null)
{
GamepadManager.Instance.SetGameObjectToSelect(((Component)value2).gameObject, true);
}
}
val.Field("m_SelectedCell").SetValue((object)0);
__instance.Decorate();
}
catch
{
}
return false;
}
}
internal static class Catalog
{
private static readonly Color JailedTile = new Color(0.6f, 0.24f, 0.22f, 1f);
private static readonly Color JailedIcon = new Color(0.38f, 0.16f, 0.15f, 1f);
private static readonly Dictionary<string, GameObject> s_Entries = new Dictionary<string, GameObject>();
public static void Track(string key, GameObject button)
{
s_Entries[key] = button;
Paint(key);
}
public static void Paint(string key)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: 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_0068: Unknown result type (might be due to invalid IL or missing references)
if (s_Entries.TryGetValue(key, out var value) && !((Object)(object)value == (Object)null))
{
bool flag = Stash.Contains(key);
Image component = value.GetComponent<Image>();
if ((Object)(object)component != (Object)null)
{
((Graphic)component).color = (flag ? JailedTile : Color.white);
}
Transform val = value.transform.Find("Icon");
if ((Object)(object)val != (Object)null)
{
((Graphic)((Component)val).GetComponent<Image>()).color = (flag ? JailedIcon : Color.white);
}
}
}
}
[HarmonyPatch(typeof(UICatalogJail), "Unit")]
internal static class Patch_CatalogUnit
{
private static void Postfix(string key, GameObject button)
{
try
{
Catalog.Track(key, button);
}
catch
{
}
}
}
[HarmonyPatch(typeof(UICatalogJail), "CanAddUnit")]
internal static class Patch_CanAddUnit
{
private static void Postfix(Unit unit, ref bool __result)
{
try
{
if (!__result && Stash.Contains(((Entity)unit).GetEntityIdentifier()))
{
__result = true;
}
}
catch
{
}
}
}
internal static class Coins
{
private const float Margin = 14f;
private const int WalkLimit = 4;
private static GameObject s_Widget;
private static Text s_Text;
public static void Show()
{
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_013a: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: 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_0172: 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)
if ((Object)(object)s_Widget != (Object)null)
{
return;
}
TitleScreenHeroSelectionManager instance = TitleScreenHeroSelectionManager.Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
Traverse val = Traverse.Create((object)instance);
Text value = val.Field("coins").GetValue<Text>();
GameObject value2 = Traverse.Create((object)AchievementManager.Instance).Field("achievementOverlay").GetValue<GameObject>();
if ((Object)(object)value == (Object)null || (Object)(object)value2 == (Object)null || (Object)(object)value2.GetComponent<RectTransform>() == (Object)null)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogWarning((object)"no coin widget to clone, the catalog opens without a counter");
}
return;
}
Transform obj = WidgetRoot(val, ((Component)value).transform);
if ((Object)(object)obj == (Object)(object)((Component)value).transform)
{
ManualLogSource log2 = Plugin.Log;
if (log2 != null)
{
log2.LogWarning((object)"the coin counter has no widget around it, cloning the number alone");
}
}
RectTransform component = ((Component)obj).GetComponent<RectTransform>();
? val2;
if (!((Object)(object)component != (Object)null))
{
val2 = Vector2.zero;
}
else
{
Rect rect = component.rect;
float width = ((Rect)(ref rect)).width;
rect = component.rect;
val2 = new Vector2(width, ((Rect)(ref rect)).height);
}
Vector2 sizeDelta = (Vector2)val2;
s_Widget = Object.Instantiate<GameObject>(((Component)obj).gameObject, value2.transform);
((Object)s_Widget).name = "UnlimitedJailCoins";
RectTransform component2 = s_Widget.GetComponent<RectTransform>();
if ((Object)(object)component2 != (Object)null)
{
component2.anchorMin = new Vector2(0f, 1f);
component2.anchorMax = new Vector2(0f, 1f);
component2.pivot = new Vector2(0f, 1f);
component2.sizeDelta = sizeDelta;
component2.anchoredPosition = new Vector2(14f, -14f);
}
Graphic[] componentsInChildren = s_Widget.GetComponentsInChildren<Graphic>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
componentsInChildren[i].raycastTarget = false;
}
s_Text = s_Widget.GetComponentInChildren<Text>(true);
Refresh();
}
public static void Hide()
{
if ((Object)(object)s_Widget != (Object)null)
{
Object.Destroy((Object)(object)s_Widget);
s_Widget = null;
s_Text = null;
}
}
public static void Refresh()
{
if ((Object)(object)s_Text != (Object)null)
{
s_Text.text = TitleScreenHeroSelectionManager.Instance.GetCoinsRemaining().ToString();
}
}
private static Transform WidgetRoot(Traverse throne, Transform coins)
{
Transform[] array = (Transform[])(object)new Transform[3]
{
Counter(throne, "shards"),
Counter(throne, "faith"),
Counter(throne, "superMetal")
};
if ((Object)(object)array[0] == (Object)null && (Object)(object)array[1] == (Object)null && (Object)(object)array[2] == (Object)null)
{
return coins;
}
Transform val = coins;
for (int i = 0; i < 4; i++)
{
Transform parent = val.parent;
if ((Object)(object)parent == (Object)null || (Object)(object)((Component)parent).GetComponent<Canvas>() != (Object)null || Holds(parent, array))
{
break;
}
val = parent;
}
return val;
}
private static bool Holds(Transform parent, Transform[] siblings)
{
foreach (Transform val in siblings)
{
if ((Object)(object)val != (Object)null && val.IsChildOf(parent))
{
return true;
}
}
return false;
}
private static Transform Counter(Traverse throne, string field)
{
Text value = throne.Field(field).GetValue<Text>();
if (!((Object)(object)value != (Object)null))
{
return null;
}
return ((Component)value).transform;
}
}
[HarmonyPatch(typeof(AchievementManager), "OpenJail")]
internal static class Patch_OpenJail
{
private static void Postfix()
{
try
{
Coins.Show();
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("could not build the coin counter: " + ex));
}
}
}
}
[HarmonyPatch(typeof(AchievementManager), "Close")]
internal static class Patch_AchievementClose
{
private static void Postfix(bool __result)
{
try
{
if (__result)
{
Coins.Hide();
}
}
catch
{
}
}
}
[HarmonyPatch(typeof(TitleScreenHeroSelectionManager), "CloseJailSelection")]
internal static class Patch_CloseJailSelection
{
private static bool Prefix()
{
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
try
{
UICatalogManager instance = UICatalogManager.Instance;
if ((Object)(object)instance == (Object)null || !instance.IsUnitDetailsOpen())
{
return true;
}
Traverse obj = Traverse.Create((object)instance);
obj.Method("CloseUnitDetails", Array.Empty<object>()).GetValue();
obj.Method("Generate", new Type[2]
{
typeof(CatalogType),
typeof(int)
}, new object[2]
{
(object)(CatalogType)7,
0
}).GetValue();
RuntimeManager.PlayOneShot("event:/SFX/UI/Cancel", default(Vector3));
return false;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("could not step back to the selection: " + ex));
}
return true;
}
}
}
[HarmonyPatch(typeof(TitleScreenHeroSelectionManager), "SelectJailedUnit")]
internal static class Patch_SelectJailedUnit
{
private static bool Prefix(string key)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
try
{
Stash.Toggle(key);
Catalog.Paint(key);
RuntimeManager.PlayOneShot(Stash.Contains(key) ? "event:/SFX/UI/Confirm" : "event:/SFX/UI/Cancel", default(Vector3));
UICatalogManager.Instance.OnSelect(key, false);
TitleScreenHeroSelectionManager.Instance.UpdateKingdomData();
Coins.Refresh();
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)("could not toggle " + key + ": " + ex));
}
}
return false;
}
}
[HarmonyPatch(typeof(TitleScreenHeroSelectionManager), "GetCoinsRemaining")]
internal static class Patch_CoinsRemaining
{
private static void Postfix(ref int __result)
{
try
{
__result = Mathf.Max(0, __result - Stash.CoinCost);
}
catch
{
}
}
}
[HarmonyPatch(typeof(ResourceManager), "GiveStartingResources")]
internal static class Patch_StartingCoins
{
private static void Postfix(ResourceManager __instance)
{
try
{
int num = Mathf.Min(Stash.CoinCost, __instance.GetCoins());
if (num > 0)
{
__instance.SpendResource((ResourceType)12, num);
}
}
catch
{
}
}
}
internal static class Stash
{
private static readonly List<string> s_Units = new List<string>();
private static string s_Key;
public static List<string> Units
{
get
{
Reload();
return s_Units;
}
}
public static int CoinCost => Mathf.Max(0, Units.Count - 3);
public static bool Contains(string entityIdentifier)
{
return Units.Contains(entityIdentifier);
}
public static void Toggle(string entityIdentifier)
{
Reload();
if (!s_Units.Remove(entityIdentifier))
{
s_Units.Add(entityIdentifier);
}
Write();
}
private static void Reload()
{
string text = CurrentKey();
if (text == s_Key)
{
return;
}
s_Key = text;
s_Units.Clear();
try
{
string path = PathFor(text);
if (!File.Exists(path))
{
return;
}
string[] array = File.ReadAllLines(path);
for (int i = 0; i < array.Length; i++)
{
string text2 = array[i].Trim();
if (text2.Length > 0 && !s_Units.Contains(text2))
{
s_Units.Add(text2);
}
}
}
catch
{
}
}
private static void Write()
{
try
{
string path = PathFor(s_Key);
Directory.CreateDirectory(Path.GetDirectoryName(path));
File.WriteAllLines(path, s_Units.ToArray());
}
catch
{
}
}
private static string CurrentKey()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
try
{
return Helper.Instance.GetRaceString(MainManager.Instance.GetSelectedKingdom(), false) + "_" + (SettingsManager.Instance.GetProfile() + 1);
}
catch
{
return "unknown";
}
}
private static string PathFor(string key)
{
return Path.Combine(Path.Combine(Paths.ConfigPath, "UnlimitedJail"), key + ".txt");
}
}
}