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.InteropServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Lamb.UI;
using Lamb.UI.FollowerSelect;
using Microsoft.CodeAnalysis;
using Spine;
using Spine.Unity;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using src.UINavigator;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Demon Summon Selector")]
[assembly: AssemblyDescription("Native Summoning Portal demon archetype selector for Cult of the Lamb")]
[assembly: AssemblyCompany("Codex")]
[assembly: AssemblyProduct("Demon Summon Selector")]
[assembly: ComVisible(false)]
[assembly: Guid("8391c6a4-9f18-4b9f-9fc4-5dbdb2a8c3ce")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyVersion("0.4.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 DemonSummonSelector
{
[BepInPlugin("com.cotl.demonsummonselector", "Demon Summon Selector", "0.4.0")]
public sealed class DemonSummonSelectorPlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.cotl.demonsummonselector";
public const string PluginName = "Demon Summon Selector";
public const string PluginVersion = "0.4.0";
private static readonly int[] SelectableDesignTypes = new int[10] { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11 };
private static readonly FieldInfo PortalDemonsField = AccessTools.Field(typeof(Interaction_DemonSummoner), "demons");
private readonly Dictionary<int, int> _effectOverrides = new Dictionary<int, int>();
private readonly Dictionary<int, int> _designOverrides = new Dictionary<int, int>();
private readonly HashSet<string> _skinWarnings = new HashSet<string>();
private ConfigEntry<bool> _enabled;
private ConfigEntry<string> _savedEffects;
private ConfigEntry<string> _savedDesigns;
private Harmony _harmony;
private float _nextPortalRefresh;
internal static DemonSummonSelectorPlugin Instance { get; private set; }
internal static ManualLogSource Log { get; private set; }
private void Awake()
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable exact Summoning Portal demon selection.");
_savedEffects = ((BaseUnityPlugin)this).Config.Bind<string>("Choices", "FollowerDemonTypes", "", "Persisted follower ID to demon combat effect choices.");
_savedDesigns = ((BaseUnityPlugin)this).Config.Bind<string>("Choices", "FollowerDemonDesigns", "", "Persisted follower ID to demon appearance choices.");
LoadChoices();
_harmony = new Harmony("com.cotl.demonsummonselector");
_harmony.PatchAll(typeof(DemonSummonSelectorPlugin).Assembly);
((BaseUnityPlugin)this).Logger.LogInfo((object)"Demon Summon Selector 0.4.0 loaded.");
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
_harmony = null;
Instance = null;
}
private void Update()
{
if (_enabled != null && _enabled.Value && !(Time.unscaledTime < _nextPortalRefresh))
{
_nextPortalRefresh = Time.unscaledTime + 0.4f;
ApplyPortalDesigns();
}
}
internal bool TryGetOverride(int followerId, out int demonType)
{
demonType = -1;
if (_enabled == null || !_enabled.Value)
{
return false;
}
if (DataManager.Instance == null)
{
return false;
}
FollowerInfo infoByID = FollowerInfo.GetInfoByID(followerId, true);
if (!CanCustomizeEffect(infoByID))
{
return false;
}
if (_effectOverrides.TryGetValue(followerId, out demonType) && demonType >= 0)
{
return demonType <= 5;
}
return false;
}
internal int GetCurrentType(FollowerInfo follower)
{
if (follower == null)
{
return -1;
}
if (!TryGetOverride(follower.ID, out var demonType))
{
return GetVanillaType(follower);
}
return demonType;
}
internal int GetCurrentDesign(FollowerInfo follower)
{
if (follower == null)
{
return -1;
}
if (!_designOverrides.TryGetValue(follower.ID, out var value) || !IsSelectableDesign(value))
{
return GetVanillaType(follower);
}
return value;
}
internal bool CanCustomizeEffect(FollowerInfo follower)
{
if (follower == null)
{
return false;
}
if (follower.Traits != null && follower.Traits.Contains((TraitType)90))
{
return false;
}
int iD = follower.ID;
if ((uint)(iD - 99994) <= 1u || iD == 100000)
{
return false;
}
return true;
}
internal bool CanCustomizeDesign(FollowerInfo follower)
{
return CanCustomizeEffect(follower);
}
internal bool CycleEffect(FollowerInfo follower, int direction)
{
if (!CanCustomizeEffect(follower) || direction == 0)
{
return false;
}
if (!_designOverrides.ContainsKey(follower.ID))
{
_designOverrides[follower.ID] = GetCurrentDesign(follower);
}
int num = GetCurrentType(follower);
if (num < 0 || num > 5)
{
num = ((direction > 0) ? (-1) : 0);
}
HashSet<int> occupiedTypes = GetOccupiedTypes(follower.ID);
for (int i = 0; i < 6; i++)
{
num = (num + ((direction > 0) ? 1 : 5)) % 6;
if (!occupiedTypes.Contains(num))
{
_effectOverrides[follower.ID] = num;
SaveChoices();
Log.LogInfo((object)("Selected " + DemonModel.GetDemonName(num) + " effect for " + follower.Name + " (" + follower.ID + ")."));
return true;
}
}
return false;
}
internal bool CycleDesign(FollowerInfo follower, int direction)
{
if (!CanCustomizeDesign(follower) || direction == 0)
{
return false;
}
int currentDesign = GetCurrentDesign(follower);
int num = Array.IndexOf(SelectableDesignTypes, currentDesign);
if (num < 0)
{
num = 0;
}
num = (num + ((direction > 0) ? 1 : (SelectableDesignTypes.Length - 1))) % SelectableDesignTypes.Length;
currentDesign = SelectableDesignTypes[num];
_designOverrides[follower.ID] = currentDesign;
SaveChoices();
Log.LogInfo((object)("Selected " + DemonModel.GetDemonName(currentDesign) + " design for " + follower.Name + " (" + follower.ID + ")."));
return true;
}
internal void RefreshFollowerButton(UIDemonSummonMenuController menu, FollowerInfo follower)
{
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Invalid comparison between Unknown and I4
if ((Object)(object)menu == (Object)null || follower == null)
{
return;
}
HashSet<int> occupiedTypes = GetOccupiedTypes(follower.ID);
foreach (FollowerInformationBox followerInfoBox in ((UIFollowerSelectBase<FollowerInformationBox>)(object)menu).FollowerInfoBoxes)
{
if (!((Object)(object)followerInfoBox == (Object)null) && ((FollowerSelectItem)followerInfoBox).FollowerInfo != null && ((FollowerSelectItem)followerInfoBox).FollowerInfo.ID == follower.ID)
{
bool flag = ((FollowerSelectItem)followerInfoBox).FollowerSelectEntry != null && (int)((FollowerSelectItem)followerInfoBox).FollowerSelectEntry.AvailabilityStatus == 0;
((FollowerSelectItem)followerInfoBox).Button.Confirmable = flag && !occupiedTypes.Contains(GetCurrentType(follower));
break;
}
}
}
internal void ApplyPreviewDesign(DemonInfoCard card, FollowerInfo follower)
{
if (!((Object)(object)card == (Object)null) && CanCustomizeEffect(follower))
{
int currentDesign = GetCurrentDesign(follower);
object? obj = AccessTools.Field(typeof(DemonInfoCard), "_demonSpine")?.GetValue(card);
SkeletonGraphic val = (SkeletonGraphic)((obj is SkeletonGraphic) ? obj : null);
object? obj2 = AccessTools.Field(typeof(DemonInfoCard), "_demonName")?.GetValue(card);
TextMeshProUGUI val2 = (TextMeshProUGUI)((obj2 is TextMeshProUGUI) ? obj2 : null);
if ((Object)(object)val != (Object)null)
{
ApplySkin(val.Skeleton, val.AnimationState, SkinName(currentDesign, follower.GetDemonLevel()), "preview");
}
if ((Object)(object)val2 != (Object)null)
{
((TMP_Text)val2).text = DemonModel.GetDemonName(currentDesign);
}
}
}
internal bool ApplyDungeonDesign(GameObject demonObject, int followerId)
{
if ((Object)(object)demonObject == (Object)null || DataManager.Instance == null)
{
return false;
}
FollowerInfo infoByID = FollowerInfo.GetInfoByID(followerId, true);
if (!CanCustomizeEffect(infoByID))
{
return true;
}
string skinName = SkinName(GetCurrentDesign(infoByID), infoByID.GetDemonLevel());
SkeletonAnimation[] componentsInChildren = demonObject.GetComponentsInChildren<SkeletonAnimation>(true);
foreach (SkeletonAnimation val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && ApplySkin(((SkeletonRenderer)val).Skeleton, val.AnimationState, skinName, ((Object)demonObject).name))
{
return true;
}
}
return false;
}
private HashSet<int> GetOccupiedTypes(int selectedFollowerId)
{
HashSet<int> hashSet = new HashSet<int>();
Interaction_DemonSummoner instance = Interaction_DemonSummoner.Instance;
if ((Object)(object)instance == (Object)null || instance.StructureInfo == null || instance.StructureInfo.MultipleFollowerIDs == null)
{
return hashSet;
}
foreach (int multipleFollowerID in instance.StructureInfo.MultipleFollowerIDs)
{
if (multipleFollowerID != -1 && multipleFollowerID != selectedFollowerId)
{
hashSet.Add(DemonModel.GetDemonType(multipleFollowerID));
}
}
return hashSet;
}
private static int GetVanillaType(FollowerInfo follower)
{
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
if (follower == null)
{
return -1;
}
if (follower.Traits != null && follower.Traits.Contains((TraitType)90))
{
return 13;
}
switch (follower.ID)
{
case 99994:
return 6;
case 99995:
return 7;
case 99990:
return 8;
case 99991:
return 9;
case 99992:
return 10;
case 99993:
return 11;
case 100000:
return 12;
default:
{
State state = Random.state;
Random.InitState(follower.ID);
int result = Random.Range(0, 6);
Random.state = state;
return result;
}
}
}
private void LoadChoices()
{
_effectOverrides.Clear();
_designOverrides.Clear();
LoadMap(_savedEffects.Value, _effectOverrides, designMap: false);
LoadMap(_savedDesigns.Value, _designOverrides, designMap: true);
}
private static void LoadMap(string raw, Dictionary<int, int> target, bool designMap)
{
if (string.IsNullOrWhiteSpace(raw))
{
return;
}
string[] array = raw.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < array.Length; i++)
{
string[] array2 = array[i].Split(new char[1] { ':' });
if (array2.Length != 2 || !int.TryParse(array2[0], out var result) || !int.TryParse(array2[1], out var result2))
{
continue;
}
bool num;
if (!designMap)
{
if (result2 < 0)
{
continue;
}
num = result2 <= 5;
}
else
{
num = IsSelectableDesign(result2);
}
if (num)
{
target[result] = result2;
}
}
}
private void SaveChoices()
{
_savedEffects.Value = SerializeMap(_effectOverrides);
_savedDesigns.Value = SerializeMap(_designOverrides);
((BaseUnityPlugin)this).Config.Save();
}
private static string SerializeMap(Dictionary<int, int> values)
{
return string.Join(";", (from pair in values
orderby pair.Key
select pair.Key + ":" + pair.Value).ToArray());
}
private static bool IsSelectableDesign(int demonType)
{
return Array.IndexOf(SelectableDesignTypes, demonType) >= 0;
}
private void ApplyPortalDesigns()
{
Interaction_DemonSummoner instance = Interaction_DemonSummoner.Instance;
if ((Object)(object)instance == (Object)null || PortalDemonsField == null || instance.StructureInfo == null || instance.StructureInfo.MultipleFollowerIDs == null || !(PortalDemonsField.GetValue(instance) is SkeletonAnimation[] array))
{
return;
}
int num = Mathf.Min(array.Length, instance.StructureInfo.MultipleFollowerIDs.Count);
for (int i = 0; i < num; i++)
{
FollowerInfo infoByID = FollowerInfo.GetInfoByID(instance.StructureInfo.MultipleFollowerIDs[i], true);
if (!((Object)(object)array[i] == (Object)null) && CanCustomizeEffect(infoByID))
{
ApplySkin(((SkeletonRenderer)array[i]).Skeleton, array[i].AnimationState, SkinName(GetCurrentDesign(infoByID), infoByID.GetDemonLevel()), "portal");
}
}
}
private static string SkinName(int design, int level)
{
if (design < 0 || design >= Interaction_DemonSummoner.DemonSkins.Length)
{
return "";
}
return Interaction_DemonSummoner.DemonSkins[design] + ((level > 1 && design < 6) ? "+" : "");
}
private bool ApplySkin(Skeleton skeleton, AnimationState animationState, string skinName, string context)
{
if (skeleton == null || string.IsNullOrEmpty(skinName))
{
return false;
}
Skin val = skeleton.Data.FindSkin(skinName);
if (val == null)
{
string item = context + ":" + skinName;
if (_skinWarnings.Add(item))
{
Log.LogWarning((object)("Demon design skin " + skinName + " is unavailable on " + context + "; keeping the effect prefab's normal appearance."));
}
return false;
}
if (skeleton.Skin != val)
{
skeleton.SetSkin(val);
skeleton.SetSlotsToSetupPose();
if (animationState != null)
{
animationState.Apply(skeleton, true);
}
}
return true;
}
}
[HarmonyPatch(typeof(DemonModel), "GetDemonType", new Type[] { typeof(int) })]
internal static class DemonTypeOverridePatch
{
private static bool Prefix(int id, ref int __result)
{
DemonSummonSelectorPlugin instance = DemonSummonSelectorPlugin.Instance;
if ((Object)(object)instance != (Object)null && instance.TryGetOverride(id, out var demonType))
{
__result = demonType;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(DemonInfoCard), "Configure")]
internal static class DemonInfoCardConfigurePatch
{
private static void Postfix(DemonInfoCard __instance, FollowerInfo followerInfo)
{
if (!((Object)(object)__instance == (Object)null) && followerInfo != null)
{
DemonChoiceCardControls demonChoiceCardControls = ((Component)__instance).GetComponent<DemonChoiceCardControls>();
if ((Object)(object)demonChoiceCardControls == (Object)null)
{
demonChoiceCardControls = ((Component)__instance).gameObject.AddComponent<DemonChoiceCardControls>();
}
demonChoiceCardControls.Configure(__instance, followerInfo);
DemonSummonSelectorPlugin.Instance?.ApplyPreviewDesign(__instance, followerInfo);
}
}
}
internal enum DemonChoiceKind
{
Design,
Effect
}
internal sealed class DemonChoiceCardControls : MonoBehaviour
{
private static readonly FieldInfo FollowerInfoField = AccessTools.Field(typeof(DemonInfoCard), "_followerInfo");
private static readonly FieldInfo DemonNameField = AccessTools.Field(typeof(DemonInfoCard), "_demonName");
private static readonly FieldInfo MenuCardControllerField = AccessTools.Field(typeof(UIDemonSummonMenuController), "_demonMenuInfoCardController");
private DemonInfoCard _card;
private DemonInfoCardController _controller;
private UIDemonSummonMenuController _menu;
private FollowerInfo _follower;
private GameObject _root;
private CanvasGroup _inputLayer;
private TextMeshProUGUI _designText;
private TextMeshProUGUI _effectText;
private TextMeshProUGUI _hintText;
private Image _designBackground;
private Image _effectBackground;
private RectTransform _designRow;
private RectTransform _effectRow;
private DemonChoiceKind _activeChoice = DemonChoiceKind.Effect;
private float _ignoreInputUntil;
private float _nextVerticalMove;
internal void Configure(DemonInfoCard card, FollowerInfo follower)
{
_card = card;
_follower = follower;
_menu = ((Component)card).GetComponentInParent<UIDemonSummonMenuController>();
if ((Object)(object)_menu == (Object)null)
{
_menu = ((Component)((Component)card).transform.root).GetComponentInChildren<UIDemonSummonMenuController>(true);
}
_controller = (DemonInfoCardController)(((Object)(object)_menu != (Object)null && MenuCardControllerField != null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)_controller == (Object)null)
{
_controller = ((Component)card).GetComponentInParent<DemonInfoCardController>();
}
if ((Object)(object)_root == (Object)null)
{
Build();
}
DemonSummonSelectorPlugin instance = DemonSummonSelectorPlugin.Instance;
bool flag = (Object)(object)instance != (Object)null && instance.CanCustomizeEffect(follower);
_root.SetActive(flag);
if (flag)
{
bool flag2 = instance.CanCustomizeDesign(follower);
if ((Object)(object)_designRow != (Object)null)
{
((Component)_designRow).gameObject.SetActive(flag2);
}
if ((Object)(object)_effectRow != (Object)null)
{
SetRect(_effectRow, 0.08f, flag2 ? 0.28f : 0.43f, 0.84f, 0.27f);
}
if (!flag2)
{
_activeChoice = DemonChoiceKind.Effect;
}
RefreshLabel();
_ignoreInputUntil = Time.unscaledTime + 0.12f;
}
}
private void Update()
{
if ((Object)(object)_root == (Object)null)
{
return;
}
bool flag = IsCurrentCard();
if ((Object)(object)_inputLayer != (Object)null)
{
_inputLayer.blocksRaycasts = flag;
_inputLayer.interactable = flag;
}
if (_root.activeSelf != flag && (Object)(object)DemonSummonSelectorPlugin.Instance != (Object)null && DemonSummonSelectorPlugin.Instance.CanCustomizeEffect(_card.FollowerInfo))
{
_root.SetActive(flag);
}
if (!flag || !_root.activeInHierarchy || Time.unscaledTime < _ignoreInputUntil)
{
return;
}
_follower = _card.FollowerInfo ?? _follower;
bool flag2 = false;
bool flag3 = false;
float num = 0f;
PlayerFarming val = null;
try
{
val = (((Object)(object)MonoSingleton<UINavigatorNew>.Instance != (Object)null) ? MonoSingleton<UINavigatorNew>.Instance.AllowInputOnlyFromPlayer : PlayerFarming.Instance);
flag2 = InputManager.UI.GetPageNavigateLeftDown(val);
flag3 = InputManager.UI.GetPageNavigateRightDown(val);
num = InputManager.UI.GetVerticalAxis(val);
}
catch
{
}
if (Input.GetKeyDown((KeyCode)91))
{
flag2 = true;
}
if (Input.GetKeyDown((KeyCode)93))
{
flag3 = true;
}
if ((Object)(object)_controller != (Object)null && !((Behaviour)_controller).enabled && (Object)(object)DemonSummonSelectorPlugin.Instance != (Object)null && DemonSummonSelectorPlugin.Instance.CanCustomizeDesign(_follower) && Time.unscaledTime >= _nextVerticalMove)
{
if (Input.GetKeyDown((KeyCode)119) || Input.GetKeyDown((KeyCode)273) || num > 0.65f)
{
SetActiveChoice(DemonChoiceKind.Design);
_nextVerticalMove = Time.unscaledTime + 0.22f;
}
else if (Input.GetKeyDown((KeyCode)115) || Input.GetKeyDown((KeyCode)274) || num < -0.65f)
{
SetActiveChoice(DemonChoiceKind.Effect);
_nextVerticalMove = Time.unscaledTime + 0.22f;
}
}
if (flag2)
{
Select(_activeChoice, -1);
}
else if (flag3)
{
Select(_activeChoice, 1);
}
RefreshInputHint(val);
}
internal void Select(DemonChoiceKind kind, int direction)
{
DemonSummonSelectorPlugin instance = DemonSummonSelectorPlugin.Instance;
if ((Object)(object)instance == (Object)null || !IsCurrentCard())
{
return;
}
_follower = _card.FollowerInfo ?? _follower;
if ((kind == DemonChoiceKind.Design) ? instance.CycleDesign(_follower, direction) : instance.CycleEffect(_follower, direction))
{
SetActiveChoice(kind);
if (kind == DemonChoiceKind.Effect)
{
instance.RefreshFollowerButton(_menu, _follower);
}
if (FollowerInfoField != null)
{
FollowerInfoField.SetValue(_card, null);
}
((UIInfoCardBase<FollowerInfo>)(object)_card).Configure(_follower);
RefreshLabel();
_ignoreInputUntil = Time.unscaledTime + 0.12f;
}
}
internal void SetActiveChoice(DemonChoiceKind kind)
{
_activeChoice = kind;
RefreshLabel();
}
private bool IsCurrentCard()
{
if ((Object)(object)_card == (Object)null || !((Component)_card).gameObject.activeInHierarchy)
{
return false;
}
if (!((Object)(object)_controller == (Object)null))
{
return (Object)(object)((UIInfoCardController<DemonInfoCard, FollowerInfo>)(object)_controller).CurrentCard == (Object)(object)_card;
}
return true;
}
private void RefreshLabel()
{
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: 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_00e1: 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_012f: Unknown result type (might be due to invalid IL or missing references)
DemonSummonSelectorPlugin instance = DemonSummonSelectorPlugin.Instance;
if (!((Object)(object)instance == (Object)null) && _follower != null)
{
int currentDesign = instance.GetCurrentDesign(_follower);
int currentType = instance.GetCurrentType(_follower);
if ((Object)(object)_designText != (Object)null)
{
((TMP_Text)_designText).text = "DESIGN " + DemonModel.GetDemonName(currentDesign);
((Graphic)_designText).color = (Color)((_activeChoice == DemonChoiceKind.Design) ? new Color(1f, 0.82f, 0.08f, 1f) : StaticColors.OffWhiteColor);
}
if ((Object)(object)_effectText != (Object)null)
{
((TMP_Text)_effectText).text = "EFFECT " + DemonModel.GetDemonName(currentType);
((Graphic)_effectText).color = (Color)((_activeChoice == DemonChoiceKind.Effect) ? new Color(1f, 0.82f, 0.08f, 1f) : StaticColors.OffWhiteColor);
}
if ((Object)(object)_designBackground != (Object)null)
{
((Graphic)_designBackground).color = RowColor(_activeChoice == DemonChoiceKind.Design);
}
if ((Object)(object)_effectBackground != (Object)null)
{
((Graphic)_effectBackground).color = RowColor(_activeChoice == DemonChoiceKind.Effect);
}
}
}
private void RefreshInputHint(PlayerFarming inputOwner)
{
if (!((Object)(object)_hintText == (Object)null))
{
bool flag = false;
try
{
flag = InputManager.General.InputIsController(inputOwner);
}
catch
{
}
((TMP_Text)_hintText).text = ((!flag) ? (DemonSummonSelectorPlugin.Instance.CanCustomizeDesign(_follower) ? "W/S SELECT [ / ] CHANGE" : "[ / ] CHANGE EFFECT") : (DemonSummonSelectorPlugin.Instance.CanCustomizeDesign(_follower) ? "UP/DOWN SELECT LB/RB CHANGE" : "LB/RB CHANGE EFFECT"));
}
}
private void Build()
{
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Expected O, but got Unknown
//IL_0119: Unknown result type (might be due to invalid IL or missing references)
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0143: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: 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_02f2: Unknown result type (might be due to invalid IL or missing references)
TextMeshProUGUI val = (TextMeshProUGUI)((DemonNameField != null) ? /*isinst with value type is only supported in some contexts*/: null);
TMP_Text val2 = (TMP_Text)(((Object)(object)val != (Object)null) ? ((object)val) : ((object)((IEnumerable<TMP_Text>)((Component)_card).GetComponentsInChildren<TMP_Text>(true)).FirstOrDefault((Func<TMP_Text, bool>)((TMP_Text text) => (Object)(object)text.font != (Object)null))));
TMP_FontAsset font = (((Object)(object)val2 != (Object)null) ? val2.font : null);
Sprite val3 = (from image in ((Component)_card).GetComponentsInChildren<Image>(true)
where (Object)(object)image.sprite != (Object)null
select image.sprite).FirstOrDefault();
_root = new GameObject("Demon Effect Selector");
RectTransform obj = _root.AddComponent<RectTransform>();
((Transform)obj).SetParent(((Object)(object)val != (Object)null) ? ((TMP_Text)val).transform : ((Component)_card).transform, false);
obj.anchorMin = new Vector2(0.5f, 0.5f);
obj.anchorMax = new Vector2(0.5f, 0.5f);
obj.sizeDelta = new Vector2(440f, 100f);
obj.anchoredPosition = new Vector2(0f, -290f);
((Transform)obj).SetAsLastSibling();
Canvas obj2 = _root.AddComponent<Canvas>();
obj2.overrideSorting = true;
obj2.sortingOrder = 30000;
_root.AddComponent<GraphicRaycaster>();
Image obj3 = _root.AddComponent<Image>();
obj3.sprite = val3;
obj3.type = (Type)(((Object)(object)val3 != (Object)null) ? 1 : 0);
((Graphic)obj3).color = new Color(0.025f, 0.02f, 0.018f, 0.97f);
((Graphic)obj3).raycastTarget = false;
_inputLayer = _root.AddComponent<CanvasGroup>();
_inputLayer.interactable = true;
_inputLayer.blocksRaycasts = true;
_inputLayer.ignoreParentGroups = false;
CreateChoiceRow("Design", DemonChoiceKind.Design, 0.58f, font, val3, out _designText, out _designBackground);
CreateChoiceRow("Effect", DemonChoiceKind.Effect, 0.28f, font, val3, out _effectText, out _effectBackground);
ref RectTransform designRow = ref _designRow;
Transform parent = ((TMP_Text)_designText).transform.parent;
designRow = (RectTransform)(object)((parent is RectTransform) ? parent : null);
ref RectTransform effectRow = ref _effectRow;
Transform parent2 = ((TMP_Text)_effectText).transform.parent;
effectRow = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
_hintText = AddText("Input Hint", _root.transform, font, 11f, (FontStyles)1);
SetRect(((TMP_Text)_hintText).rectTransform, 0.08f, 0.01f, 0.84f, 0.18f);
((TMP_Text)_hintText).alignment = (TextAlignmentOptions)514;
((Graphic)_hintText).color = new Color(0.75f, 0.69f, 0.61f, 1f);
}
private void CreateChoiceRow(string name, DemonChoiceKind kind, float y, TMP_FontAsset font, Sprite sprite, out TextMeshProUGUI label, out Image background)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
GameObject val = new GameObject(name + " Row");
RectTransform obj = val.AddComponent<RectTransform>();
((Transform)obj).SetParent(_root.transform, false);
SetRect(obj, 0.08f, y, 0.84f, 0.27f);
background = val.AddComponent<Image>();
background.sprite = sprite;
background.type = (Type)(((Object)(object)sprite != (Object)null) ? 1 : 0);
((Graphic)background).raycastTarget = false;
label = AddText(name + " Label", val.transform, font, 14f, (FontStyles)1);
SetRect(((TMP_Text)label).rectTransform, 0.17f, 0f, 0.66f, 1f);
((TMP_Text)label).alignment = (TextAlignmentOptions)514;
CreateArrow("Previous " + name, val.transform, font, sprite, kind, next: false);
CreateArrow("Next " + name, val.transform, font, sprite, kind, next: true);
}
private void CreateArrow(string name, Transform parent, TMP_FontAsset font, Sprite sprite, DemonChoiceKind kind, bool next)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Expected O, but got Unknown
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: 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_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
RectTransform obj = val.AddComponent<RectTransform>();
((Transform)obj).SetParent(parent, false);
obj.anchorMin = new Vector2(next ? 1f : 0f, 0.5f);
obj.anchorMax = obj.anchorMin;
obj.sizeDelta = new Vector2(43f, 38f);
obj.anchoredPosition = new Vector2(next ? (-22f) : 22f, 0f);
Image val2 = val.AddComponent<Image>();
((Graphic)val2).color = new Color(0.52f, 0.035f, 0.025f, 0.98f);
((Graphic)val2).raycastTarget = true;
if ((Object)(object)sprite != (Object)null)
{
val2.sprite = sprite;
val2.type = (Type)1;
}
TextMeshProUGUI obj2 = AddText("Glyph", val.transform, font, 32f, (FontStyles)1);
SetRect(((TMP_Text)obj2).rectTransform, 0f, 0f, 1f, 1f);
((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
((Graphic)obj2).color = Color.white;
((TMP_Text)obj2).text = (next ? ">" : "<");
((Graphic)obj2).raycastTarget = false;
val.AddComponent<DemonArrowClick>().Configure(this, kind, next ? 1 : (-1), val2);
}
private static TextMeshProUGUI AddText(string name, Transform parent, TMP_FontAsset font, float size, FontStyles style)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
((Transform)val.AddComponent<RectTransform>()).SetParent(parent, false);
TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj).font = font;
((TMP_Text)obj).fontSize = size;
((TMP_Text)obj).fontStyle = style;
((TMP_Text)obj).enableWordWrapping = false;
((TMP_Text)obj).overflowMode = (TextOverflowModes)1;
((Graphic)obj).raycastTarget = false;
return obj;
}
private static void SetRect(RectTransform rect, float x, float y, float width, float height)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
rect.anchorMin = new Vector2(x, y);
rect.anchorMax = new Vector2(x + width, y + height);
rect.offsetMin = Vector2.zero;
rect.offsetMax = Vector2.zero;
}
private static Color RowColor(bool active)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
if (!active)
{
return new Color(0.055f, 0.045f, 0.04f, 0.88f);
}
return new Color(0.26f, 0.035f, 0.025f, 0.96f);
}
}
internal sealed class DemonArrowClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler
{
private DemonChoiceCardControls _owner;
private DemonChoiceKind _kind;
private int _direction;
private Image _image;
private Color _normal;
internal void Configure(DemonChoiceCardControls owner, DemonChoiceKind kind, int direction, Image image)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
_owner = owner;
_kind = kind;
_direction = direction;
_image = image;
_normal = ((Graphic)image).color;
}
public void OnPointerClick(PointerEventData eventData)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if ((int)eventData.button == 0)
{
_owner.Select(_kind, _direction);
}
}
public void OnPointerEnter(PointerEventData eventData)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
_owner.SetActiveChoice(_kind);
if ((Object)(object)_image != (Object)null)
{
((Graphic)_image).color = new Color(0.78f, 0.08f, 0.035f, 1f);
}
}
public void OnPointerExit(PointerEventData eventData)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_image != (Object)null)
{
((Graphic)_image).color = _normal;
}
}
}
[HarmonyPatch(typeof(Demon), "Init")]
internal static class DemonInitDesignPatch
{
private static void Postfix(Demon __instance, int followerID)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)DemonSummonSelectorPlugin.Instance == (Object)null))
{
DemonDesignApplicator demonDesignApplicator = ((Component)__instance).GetComponent<DemonDesignApplicator>();
if ((Object)(object)demonDesignApplicator == (Object)null)
{
demonDesignApplicator = ((Component)__instance).gameObject.AddComponent<DemonDesignApplicator>();
}
demonDesignApplicator.Configure(followerID);
}
}
}
internal sealed class DemonDesignApplicator : MonoBehaviour
{
private int _followerId;
private Coroutine _routine;
internal void Configure(int followerId)
{
_followerId = followerId;
if (_routine != null)
{
((MonoBehaviour)this).StopCoroutine(_routine);
}
_routine = ((MonoBehaviour)this).StartCoroutine(ApplyAfterVanillaSkin());
}
private IEnumerator ApplyAfterVanillaSkin()
{
yield return null;
Apply();
yield return (object)new WaitForSecondsRealtime(0.15f);
Apply();
yield return (object)new WaitForSecondsRealtime(0.45f);
Apply();
yield return (object)new WaitForSecondsRealtime(0.8f);
Apply();
Object.Destroy((Object)(object)this);
}
private void Apply()
{
DemonSummonSelectorPlugin.Instance?.ApplyDungeonDesign(((Component)this).gameObject, _followerId);
}
}
}