using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ForgeSmartToggle.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ForgeSmartToggle")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+0580c109fdc9332d96bdc49e1df286cd93811e63")] [assembly: AssemblyProduct("ForgeSmartToggle")] [assembly: AssemblyTitle("ForgeSmartToggle")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 ForgeSmartToggle { [BepInPlugin("ForgeSmartToggle", "ForgeSmartToggle", "0.1.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger = new ManualLogSource("ForgeSmartToggle"); public void Awake() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin ForgeSmartToggle is loaded!"); HybridForgePatch.Init(((BaseUnityPlugin)this).Config); new Harmony("ForgeSmartToggle").PatchAll(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "ForgeSmartToggle"; public const string PLUGIN_NAME = "ForgeSmartToggle"; public const string PLUGIN_VERSION = "0.1.0"; } } namespace ForgeSmartToggle.Patches { internal static class HybridForgePatch { [HarmonyPatch(typeof(SaveManager), "ToggleForgeActive")] private static class Cycle { private static bool Prefix(SaveManager __instance) { if (!enabled.Value) { hybrid = false; return true; } if (__instance.IsForgeToggleActive() && !hybrid) { hybrid = true; return false; } hybrid = false; return true; } } [HarmonyPatch(typeof(SaveManager), "SetForgeToggleActive")] private static class ClearOnDirectSet { private static void Prefix(SaveManager __instance, bool isActive) { if (__instance.IsForgeToggleActive() != isActive) { hybrid = false; } } } [HarmonyPatch(typeof(PlayerManager), "OnCardPlayedPreEffectsFired")] private static class SkipForgeOnPlay { private static bool Prefix(CardState cardState, bool fromDirectPlay, ref IEnumerator __result) { if (!hybrid || !fromDirectPlay || cardState == null || !IsSkipped(cardState)) { return true; } Plugin.Logger.LogDebug((object)("Hybrid forge: skipping '" + cardState.GetTitle() + "'")); __result = Nothing(); return false; } private static IEnumerator Nothing() { yield break; } } [HarmonyPatch(typeof(ForgePointsUI), "SetStateForgingActive")] private static class MarkToggle { private static void Postfix(ForgePointsUI __instance) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_0056: 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_006e: Unknown result type (might be due to invalid IL or missing references) GameObject value = Traverse.Create((object)__instance).Field("forgingActiveToggle").Value; if ((Object)(object)value == (Object)null) { return; } RefreshBadge(__instance, value); Graphic componentInChildren = value.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { Color valueOrDefault = originalTint.GetValueOrDefault(); if (!originalTint.HasValue) { valueOrDefault = componentInChildren.color; originalTint = valueOrDefault; } componentInChildren.color = (hybrid ? HybridTint : originalTint.Value); } Traverse.Create((object)__instance).Method("RefreshTooltip", Array.Empty()).GetValue(); } } [HarmonyPatch(typeof(ForgePointsUI), "SetTooltip")] private static class TooltipNote { private static void Prefix(ref string title, ref string body) { if (hybrid) { title += " (Hybrid)"; string text = SkippedList(); body += ((text.Length > 0) ? ("\n\nHybrid forging (the H on the button): Forge Points are spent as usual, except on these units, which are ignored:\n" + text + "") : "\n\nHybrid forging: no units are ignored - the ignore list in BepInEx/config/ForgeSmartToggle.cfg is empty."); } } } private static ConfigEntry enabled = null; private static ConfigEntry skippedSubtypes = null; private static bool hybrid; private static Color? originalTint; private static TextMeshProUGUI? hybridBadge; private static readonly Color HybridTint = new Color(1f, 0.69f, 0.13f); public static void Init(ConfigFile config) { enabled = config.Bind("Hybrid", "Enabled", true, "Enable the Hybrid forge state. When disabled, the toggle stays plain Off -> On -> Off."); skippedSubtypes = config.Bind("Hybrid", "SkippedSubtypes", "Morsel, Imp, Whelp", "Comma-separated unit subtypes that do NOT consume Forge Points while the forge toggle is in its Hybrid state. Matched case-insensitively as a substring of both the subtype key and its localized name."); SelfCheck(); } internal static bool Matches(string subtypeKey, string localizedName, string configuredList) { string[] array = configuredList.Split(','); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && (subtypeKey.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || localizedName.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)) { return true; } } return false; } private static void SelfCheck() { if (!Matches("SubtypeData_Morsel", "Morsel", "Morsel, Imp, Whelp") || !Matches("SubtypeData_Imp", "Imp", "Morsel, Imp, Whelp") || !Matches("whatever", "Whelp", "Morsel, Imp, Whelp") || Matches("SubtypeData_Dragon", "Dragon", "Morsel, Imp, Whelp") || Matches("SubtypeData_Imp", "Imp", " , ")) { throw new InvalidOperationException("HybridForgePatch.Matches self-check failed"); } } private static bool IsSkipped(CardState card) { CharacterData spawnCharacterData = card.GetSpawnCharacterData(); List list = ((spawnCharacterData != null) ? spawnCharacterData.GetSubtypes() : null); if (list == null) { return false; } foreach (SubtypeData item in list) { if (Matches(item.Key ?? string.Empty, item.LocalizedName ?? string.Empty, skippedSubtypes.Value)) { return true; } } return false; } private static string SkippedList() { IEnumerable values = from entry in skippedSubtypes.Value.Split(',') select entry.Trim() into entry where entry.Length > 0 select entry; return string.Join(", ", values); } private static void RefreshBadge(ForgePointsUI ui, GameObject toggle) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00dd: 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_00fc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hybridBadge == (Object)null) { TextMeshProUGUI value = Traverse.Create((object)ui).Field("countLabel").Value; if ((Object)(object)value == (Object)null) { return; } hybridBadge = Object.Instantiate(value, toggle.transform); ((Object)hybridBadge).name = "HybridBadge"; ((TMP_Text)hybridBadge).text = "H"; ((TMP_Text)hybridBadge).fontSize = ((TMP_Text)value).fontSize * 0.65f; ((Graphic)hybridBadge).color = HybridTint; ((TMP_Text)hybridBadge).alignment = (TextAlignmentOptions)514; ((Graphic)hybridBadge).raycastTarget = false; RectTransform rectTransform = ((TMP_Text)hybridBadge).rectTransform; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(1f, 0f); rectTransform.anchorMax = val; rectTransform.anchorMin = val; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; rectTransform.sizeDelta = new Vector2(28f, 28f); ((Transform)rectTransform).localScale = Vector3.one; } ((Component)hybridBadge).gameObject.SetActive(hybrid); } } }