using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("StarterSpells")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+17c41af0f5c60e5505c351425aafe43d32ba5ec4")]
[assembly: AssemblyProduct("StarterSpells")]
[assembly: AssemblyTitle("StarterSpells")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[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 StarterSpells
{
[HarmonyPatch]
internal static class LocalWizard
{
private static LocalPlayer player;
private static CharacterId? lastSelected;
private static float nextFind;
private static bool loggedFailure;
internal static LocalPlayer Player
{
get
{
if ((Object)(object)player != (Object)null && !((Il2CppObjectBase)player).WasCollected)
{
return player;
}
player = null;
try
{
player = SingletonPersistent<LocalPlayer>.Instance;
}
catch
{
}
if ((Object)(object)player == (Object)null && Time.unscaledTime >= nextFind)
{
nextFind = Time.unscaledTime + 1f;
try
{
player = Object.FindObjectOfType<LocalPlayer>();
}
catch
{
}
}
return player;
}
}
internal static CharacterId? Current
{
get
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
LocalPlayer val = Player;
if ((Object)(object)val != (Object)null)
{
try
{
return lastSelected = val.GetSelectedCharacter();
}
catch (Exception ex)
{
LogOnce("reading the selected wizard failed: " + ex.Message);
}
}
if (lastSelected.HasValue)
{
return lastSelected;
}
LogOnce("the game's LocalPlayer object wasn't found yet");
return null;
}
}
private static void LogOnce(string why)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
if (!loggedFailure)
{
loggedFailure = true;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(66, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Picker can't tell which wizard is selected: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(why);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". It will keep trying.");
}
log.LogWarning(val);
}
}
[HarmonyPatch(typeof(LocalPlayer), "SetSelectedCharacter")]
[HarmonyPostfix]
private static void SetSelected(LocalPlayer __instance, CharacterId character)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
player = __instance;
lastSelected = character;
}
[HarmonyPatch(typeof(LocalPlayer), "LoadSelectedCharacter")]
[HarmonyPostfix]
private static void LoadSelected(LocalPlayer __instance)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
player = __instance;
try
{
lastSelected = __instance.GetSelectedCharacter();
}
catch
{
}
}
}
public class PickerUI : MonoBehaviour
{
private GameObject canvasGo;
private GameObject panel;
private TextMeshProUGUI title;
private TextMeshProUGUI value;
private TextMeshProUGUI hint;
private Image icon;
private float nextScan;
private bool inMenu;
private bool hidden;
private CharacterId shownCharacter = (CharacterId)(-1);
private string shownChoice;
private static Action prevAction;
private static Action nextAction;
private static UnityAction prevUnity;
private static UnityAction nextUnity;
private static PickerUI instance;
private float nextErrorLog;
public PickerUI(IntPtr ptr)
: base(ptr)
{
}//IL_0002: Unknown result type (might be due to invalid IL or missing references)
private void Update()
{
instance = this;
if (Time.unscaledTime >= nextScan)
{
nextScan = Time.unscaledTime + 0.5f;
Step("menu check", delegate
{
bool flag = (Object)(object)Object.FindObjectOfType<MainMenuManager>() != (Object)null;
bool flag2 = (Object)(object)Object.FindObjectOfType<RunManager>() != (Object)null;
inMenu = flag && !flag2;
});
}
bool show = inMenu && Plugin.ShowPicker.Value && !hidden;
if (show && (Object)(object)panel == (Object)null)
{
Step("build", Build);
}
if ((Object)(object)canvasGo != (Object)null && canvasGo.activeSelf != show)
{
Step("show/hide", delegate
{
canvasGo.SetActive(show);
});
}
if (inMenu)
{
Step("keys", HandleKeys);
}
if (show && (Object)(object)panel != (Object)null)
{
Step("refresh", delegate
{
Refresh(force: false);
});
}
}
private void Step(string what, Action action)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
try
{
action();
}
catch (Exception ex)
{
if (!(Time.unscaledTime < nextErrorLog))
{
nextErrorLog = Time.unscaledTime + 10f;
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(11, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Picker (");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(what);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
}
log.LogError(val);
}
}
}
private static bool Pressed(string keyName)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
Keyboard current = Keyboard.current;
if (current == null || string.IsNullOrEmpty(keyName))
{
return false;
}
if (!Enum.TryParse<Key>(keyName, ignoreCase: true, out Key result) || (int)result == 0)
{
return false;
}
KeyControl val = current[result];
if (val != null)
{
return ((ButtonControl)val).wasPressedThisFrame;
}
return false;
}
private void HandleKeys()
{
if (Pressed(Plugin.ToggleKey.Value))
{
hidden = !hidden;
}
if (!hidden && Plugin.ShowPicker.Value)
{
if (Pressed(Plugin.PrevKey.Value))
{
Cycle(-1);
}
if (Pressed(Plugin.NextKey.Value))
{
Cycle(1);
}
}
}
private static void Cycle(int dir)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
CharacterId? val = CurrentCharacter();
if (val.HasValue && Plugin.Choices.TryGetValue(val.Value, out var val2))
{
List<string> list = Spells.Options();
int num = list.IndexOf(val2.Value);
if (num < 0)
{
num = 0;
}
num = (num + dir + list.Count) % list.Count;
val2.Value = list[num];
instance?.Refresh(force: true);
}
}
private static CharacterId? CurrentCharacter()
{
return LocalWizard.Current;
}
private void Refresh(bool force)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_010c: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
//IL_0252: Unknown result type (might be due to invalid IL or missing references)
//IL_0259: Expected O, but got Unknown
//IL_0216: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0235: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)panel == (Object)null)
{
return;
}
CharacterId? val = CurrentCharacter();
if (!val.HasValue || !Plugin.Choices.TryGetValue(val.Value, out var val2))
{
if (!(shownChoice == "<none>") || force)
{
shownChoice = "<none>";
shownCharacter = (CharacterId)(-1);
((TMP_Text)title).text = "STARTING SPELL";
((TMP_Text)value).text = "Pick a wizard first";
((Graphic)value).color = new Color(1f, 1f, 1f, 0.7f);
SetIcon(null, dimmed: false);
Plugin.Log.LogInfo((object)"Picker: no wizard selected yet.");
}
return;
}
string text = val2.Value;
if (force || val.Value != shownCharacter || !(text == shownChoice))
{
shownCharacter = val.Value;
shownChoice = text;
((TMP_Text)title).text = "STARTING SPELL - " + Spells.WizardName(val.Value);
SpellType? val3 = Spells.ChoiceFor(val.Value);
SpellType result;
if (val3.HasValue)
{
((TMP_Text)value).text = Spells.SpellName(val3.Value);
((Graphic)value).color = new Color(1f, 0.85f, 0.35f);
SetIcon(val3.Value, dimmed: false);
}
else if (text != "Default" && Enum.TryParse<SpellType>(text, out result))
{
((TMP_Text)value).text = Spells.SpellName(result) + " (locked)";
((Graphic)value).color = new Color(1f, 1f, 1f, 0.6f);
SetIcon(result, dimmed: true);
}
else
{
SpellType? spell = Spells.NormalSpellFor(val.Value);
((TMP_Text)value).text = (spell.HasValue ? ("Default (" + Spells.SpellName(spell.Value) + ")") : "Default");
((Graphic)value).color = Color.white;
SetIcon(spell, dimmed: false);
}
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(11, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Picker: ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((TMP_Text)title).text);
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" | ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(((TMP_Text)value).text);
}
log.LogInfo(val4);
}
}
private void SetIcon(SpellType? spell, bool dimmed)
{
//IL_001d: 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_004f: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)icon == (Object)null))
{
Sprite val = (spell.HasValue ? Spells.Icon(spell.Value) : null);
icon.sprite = val;
((Behaviour)icon).enabled = (Object)(object)val != (Object)null;
((Graphic)icon).color = (Color)(dimmed ? new Color(0.45f, 0.45f, 0.45f, 0.8f) : Color.white);
}
}
private void Build()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0085: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_019d: Unknown result type (might be due to invalid IL or missing references)
//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
//IL_020c: Unknown result type (might be due to invalid IL or missing references)
//IL_021b: Unknown result type (might be due to invalid IL or missing references)
//IL_0277: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
//IL_03fd: Unknown result type (might be due to invalid IL or missing references)
TMP_FontAsset val = null;
TextMeshProUGUI val2 = Object.FindObjectOfType<TextMeshProUGUI>();
if ((Object)(object)val2 != (Object)null)
{
val = ((TMP_Text)val2).font;
}
if ((Object)(object)val == (Object)null)
{
val = TMP_Settings.defaultFontAsset;
}
if ((Object)(object)val == (Object)null)
{
return;
}
canvasGo = new GameObject("StarterSpells_Canvas");
Object.DontDestroyOnLoad((Object)(object)canvasGo);
Canvas obj = canvasGo.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 500;
CanvasScaler obj2 = canvasGo.AddComponent<CanvasScaler>();
obj2.uiScaleMode = (ScaleMode)1;
obj2.referenceResolution = new Vector2(1920f, 1080f);
obj2.matchWidthOrHeight = 0.5f;
canvasGo.AddComponent<GraphicRaycaster>();
panel = NewRect("Panel", canvasGo.transform);
((Graphic)panel.AddComponent<Image>()).color = new Color(0.08f, 0.05f, 0.14f, 0.85f);
RectTransform component = panel.GetComponent<RectTransform>();
component.sizeDelta = new Vector2(600f, 150f);
Anchor(component, Plugin.PickerPosition.Value);
title = NewText("Title", panel.transform, val, 20f, new Vector2(0f, 46f), new Vector2(580f, 40f));
((Graphic)title).color = new Color(0.75f, 0.7f, 0.95f);
GameObject val3 = NewRect("Icon", panel.transform);
RectTransform component2 = val3.GetComponent<RectTransform>();
component2.anchoredPosition = new Vector2(-160f, 2f);
component2.sizeDelta = new Vector2(64f, 64f);
icon = val3.AddComponent<Image>();
icon.preserveAspect = true;
((Graphic)icon).raycastTarget = false;
((Behaviour)icon).enabled = false;
value = NewText("Value", panel.transform, val, 30f, new Vector2(38f, 2f), new Vector2(320f, 56f));
((TMP_Text)value).enableAutoSizing = true;
((TMP_Text)value).fontSizeMin = 18f;
((TMP_Text)value).fontSizeMax = 30f;
hint = NewText("Hint", panel.transform, val, 15f, new Vector2(0f, -48f), new Vector2(580f, 32f));
((Graphic)hint).color = new Color(1f, 1f, 1f, 0.5f);
((TMP_Text)hint).text = $"{Plugin.PrevKey.Value} / {Plugin.NextKey.Value} to change - {Plugin.ToggleKey.Value} to hide";
if (prevAction == null)
{
prevAction = delegate
{
Cycle(-1);
};
}
if (nextAction == null)
{
nextAction = delegate
{
Cycle(1);
};
}
if (prevUnity == null)
{
prevUnity = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)prevAction);
}
if (nextUnity == null)
{
nextUnity = DelegateSupport.ConvertDelegate<UnityAction>((Delegate)nextAction);
}
NewButton("Prev", panel.transform, val, "<", new Vector2(-235f, 2f), prevUnity);
NewButton("Next", panel.transform, val, ">", new Vector2(235f, 2f), nextUnity);
Refresh(force: true);
Plugin.Log.LogInfo((object)"Starting-spell picker ready.");
}
private static GameObject NewRect(string name, Transform parent)
{
//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_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
GameObject val = new GameObject(name);
val.AddComponent<RectTransform>();
val.transform.SetParent(parent, false);
return val;
}
private static TextMeshProUGUI NewText(string name, Transform parent, TMP_FontAsset font, float size, Vector2 pos, Vector2 box)
{
//IL_000e: 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_0050: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = NewRect(name, parent);
RectTransform component = obj.GetComponent<RectTransform>();
component.anchoredPosition = pos;
component.sizeDelta = box;
TextMeshProUGUI obj2 = obj.AddComponent<TextMeshProUGUI>();
((TMP_Text)obj2).font = font;
((TMP_Text)obj2).fontSize = size;
((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
((TMP_Text)obj2).textWrappingMode = (TextWrappingModes)0;
((TMP_Text)obj2).overflowMode = (TextOverflowModes)0;
((Graphic)obj2).raycastTarget = false;
((Graphic)obj2).color = Color.white;
return obj2;
}
private static void NewButton(string name, Transform parent, TMP_FontAsset font, string label, Vector2 pos, UnityAction onClick)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
GameObject val = NewRect(name, parent);
RectTransform component = val.GetComponent<RectTransform>();
component.anchoredPosition = pos;
component.sizeDelta = new Vector2(56f, 48f);
Image val2 = val.AddComponent<Image>();
((Graphic)val2).color = new Color(0.35f, 0.22f, 0.6f, 0.95f);
Button obj = val.AddComponent<Button>();
((Selectable)obj).targetGraphic = (Graphic)(object)val2;
((UnityEvent)obj.onClick).AddListener(onClick);
((TMP_Text)NewText("Label", val.transform, font, 30f, Vector2.zero, component.sizeDelta)).text = label;
}
private static void Anchor(RectTransform rt, string where)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: 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)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: 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_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: 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_0083: 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_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: 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)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
Vector2 val = (rt.pivot = (rt.anchorMax = (rt.anchorMin = (Vector2)(where switch
{
"TopLeft" => new Vector2(0f, 1f),
"TopRight" => new Vector2(1f, 1f),
"BottomLeft" => new Vector2(0f, 0f),
"BottomRight" => new Vector2(1f, 0f),
"BottomCenter" => new Vector2(0.5f, 0f),
_ => new Vector2(0.5f, 1f),
}))));
rt.anchoredPosition = new Vector2((val.x == 0f) ? 24f : ((val.x == 1f) ? (-24f) : 0f), (val.y == 1f) ? (-24f) : 24f);
}
}
[BepInPlugin("girthy_mods.StarterSpells", "StarterSpells", "1.1.0")]
public class Plugin : BasePlugin
{
public const string Guid = "girthy_mods.StarterSpells";
public const string Name = "StarterSpells";
public const string Version = "1.1.0";
internal static ManualLogSource Log;
internal const string DefaultChoice = "Default";
internal static readonly Dictionary<CharacterId, ConfigEntry<string>> Choices = new Dictionary<CharacterId, ConfigEntry<string>>();
internal static ConfigEntry<bool> AllowLockedSpells;
internal static ConfigEntry<bool> ShowPicker;
internal static ConfigEntry<string> PrevKey;
internal static ConfigEntry<string> NextKey;
internal static ConfigEntry<string> ToggleKey;
internal static ConfigEntry<string> PickerPosition;
public override void Load()
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Invalid comparison between Unknown and I4
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: 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_0112: Expected O, but got Unknown
//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Expected O, but got Unknown
//IL_0252: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
//IL_0286: Unknown result type (might be due to invalid IL or missing references)
//IL_028d: Expected O, but got Unknown
Log = ((BasePlugin)this).Log;
List<string> list = new List<string> { "Default" };
foreach (SpellType value in Enum.GetValues(typeof(SpellType)))
{
list.Add(((object)value/*cast due to .constrained prefix*/).ToString());
}
AcceptableValueList<string> val = new AcceptableValueList<string>(list.ToArray());
foreach (CharacterId value2 in Enum.GetValues(typeof(CharacterId)))
{
if ((int)value2 != 99999)
{
Choices[value2] = ((BasePlugin)this).Config.Bind<string>("Starting Spells", ((object)value2/*cast due to .constrained prefix*/).ToString(), "Default", new ConfigDescription($"Starting spell for {value2}. Default = the wizard's normal spell.", (AcceptableValueBase)(object)val, Array.Empty<object>()));
}
}
AllowLockedSpells = ((BasePlugin)this).Config.Bind<bool>("General", "AllowLockedSpells", false, "Allow starting with spells you haven't unlocked yet. Off = only spells you've unlocked.");
ShowPicker = ((BasePlugin)this).Config.Bind<bool>("Picker", "ShowPicker", true, "Show the starting-spell picker in the main menu.");
PickerPosition = ((BasePlugin)this).Config.Bind<string>("Picker", "ScreenPosition", "BottomCenter", new ConfigDescription("Where the picker sits on screen.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[6] { "TopCenter", "TopLeft", "TopRight", "BottomLeft", "BottomRight", "BottomCenter" }), Array.Empty<object>()));
PrevKey = ((BasePlugin)this).Config.Bind<string>("Picker", "PreviousKey", "F6", "Key for the previous spell (Unity Input System key name).");
NextKey = ((BasePlugin)this).Config.Bind<string>("Picker", "NextKey", "F7", "Key for the next spell.");
ToggleKey = ((BasePlugin)this).Config.Bind<string>("Picker", "ToggleKey", "F8", "Key to show or hide the picker.");
Harmony val3 = new Harmony("girthy_mods.StarterSpells");
val3.PatchAll(typeof(StarterPatches));
val3.PatchAll(typeof(LocalWizard));
((BasePlugin)this).AddComponent<PickerUI>();
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(8, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>("StarterSpells");
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>("1.1.0");
((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" ready.");
}
log.LogInfo(val4);
}
}
internal static class Spells
{
private static readonly Dictionary<string, string> nameCache = new Dictionary<string, string>();
internal static SpellType? ChoiceFor(CharacterId character)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
if (!Plugin.Choices.TryGetValue(character, out var value))
{
return null;
}
string value2 = value.Value;
if (string.IsNullOrEmpty(value2) || value2 == "Default")
{
return null;
}
if (!Enum.TryParse<SpellType>(value2, out SpellType result))
{
return null;
}
if (!Plugin.AllowLockedSpells.Value && IsLocked(result))
{
return null;
}
return result;
}
internal static bool IsLocked(SpellType spell)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
try
{
SpellConfiguration val = SpellConfigurationRepository.Get(spell);
return (Object)(object)val != (Object)null && val.IsLockedByProgression();
}
catch
{
return false;
}
}
internal static List<string> Options()
{
//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_0040: Unknown result type (might be due to invalid IL or missing references)
List<string> list = new List<string> { "Default" };
foreach (SpellType value in Enum.GetValues(typeof(SpellType)))
{
if (Plugin.AllowLockedSpells.Value || !IsLocked(value))
{
list.Add(((object)value/*cast due to .constrained prefix*/).ToString());
}
}
return list;
}
internal static SpellType? NormalSpellFor(CharacterId character)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: 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)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
try
{
CharacterResource val = CharacterResourceRepository.Get(character);
LocalPlayer player = LocalWizard.Player;
SkinId val2 = ((player != null) ? player.GetSelectedSkin() : val.DefaultSkin);
StarterPatches.Bypass = true;
try
{
return val.GetInitialSpell(val2);
}
finally
{
StarterPatches.Bypass = false;
}
}
catch
{
return null;
}
}
internal static Sprite Icon(SpellType spell)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
try
{
SpellConfiguration obj = SpellConfigurationRepository.Get(spell);
SpellIconContainer val = ((obj != null) ? obj.IconContainer : null);
if (val == null)
{
return null;
}
return val.DefaultIcon ?? val.GetIcon((ElementType)0);
}
catch
{
return null;
}
}
internal unsafe static string SpellName(SpellType spell)
{
return Localized("SpellName_" + ((object)(*(SpellType*)(&spell))/*cast due to .constrained prefix*/).ToString(), Pretty(((object)(*(SpellType*)(&spell))/*cast due to .constrained prefix*/).ToString()));
}
internal unsafe static string WizardName(CharacterId c)
{
return Localized("Character_" + ((object)(*(CharacterId*)(&c))/*cast due to .constrained prefix*/).ToString(), Pretty(((object)(*(CharacterId*)(&c))/*cast due to .constrained prefix*/).ToString()));
}
private static string Localized(string key, string fallback)
{
if (nameCache.TryGetValue(key, out var value))
{
return value;
}
string text = null;
try
{
LocalizedStringDatabase stringDatabase = LocalizationSettings.StringDatabase;
if (stringDatabase != null)
{
text = stringDatabase.GetLocalizedString(TableEntryReference.op_Implicit(key), (Locale)null, (FallbackBehavior)0, (Il2CppReferenceArray<Object>)null);
}
}
catch
{
}
int num;
if (!string.IsNullOrWhiteSpace(text) && text != key)
{
num = ((!text.Contains("No translation found")) ? 1 : 0);
if (num != 0)
{
nameCache[key] = text;
}
}
else
{
num = 0;
}
if (num == 0)
{
return fallback;
}
return text;
}
private static string Pretty(string id)
{
if (id == "Smg")
{
return "SMG";
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < id.Length; i++)
{
if (i > 0 && char.IsUpper(id[i]) && !char.IsUpper(id[i - 1]))
{
stringBuilder.Append(' ');
}
stringBuilder.Append(id[i]);
}
return stringBuilder.ToString();
}
}
[HarmonyPatch]
internal static class StarterPatches
{
[ThreadStatic]
private static int context;
[ThreadStatic]
internal static bool Bypass;
private static bool IsLocalOwner(NetworkBehaviour nb)
{
try
{
if (nb.IsOwner)
{
return true;
}
NetworkManager singleton = NetworkManager.Singleton;
return (Object)(object)singleton == (Object)null || !singleton.IsListening;
}
catch
{
return false;
}
}
[HarmonyPatch(typeof(CharacterResource), "GetInitialSpell")]
[HarmonyPostfix]
private static void GetInitialSpell_Postfix(CharacterResource __instance, ref SpellType __result)
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected I4, but got Unknown
if (context <= 0 || Bypass)
{
return;
}
try
{
SpellType? val = Spells.ChoiceFor(__instance.Id);
if (val.HasValue)
{
__result = (SpellType)(int)val.Value;
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(17, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("GetInitialSpell: ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(ex);
}
log.LogError(val2);
}
}
[HarmonyPatch(typeof(GameplayPlayerIdentity), "InitializeOnClientsRpc")]
[HarmonyPrefix]
private static void InitRpc_Prefix(GameplayPlayerIdentity __instance, out bool __state)
{
__state = IsLocalOwner((NetworkBehaviour)(object)__instance);
if (__state)
{
context++;
}
}
[HarmonyPatch(typeof(GameplayPlayerIdentity), "InitializeOnClientsRpc")]
[HarmonyPostfix]
private static void InitRpc_Postfix(GameplayPlayerIdentity __instance, bool __state)
{
if (__state)
{
context = Math.Max(0, context - 1);
LogEquip(__instance);
}
}
[HarmonyPatch(typeof(GameplayPlayerIdentity), "Initialize")]
[HarmonyPrefix]
private static void Init_Prefix(GameplayPlayerIdentity __instance, out bool __state)
{
__state = IsLocalOwner((NetworkBehaviour)(object)__instance);
if (__state)
{
context++;
}
}
[HarmonyPatch(typeof(GameplayPlayerIdentity), "Initialize")]
[HarmonyPostfix]
private static void Init_Postfix(GameplayPlayerIdentity __instance, bool __state)
{
if (__state)
{
context = Math.Max(0, context - 1);
LogEquip(__instance);
}
}
[HarmonyPatch(typeof(GameplayPlayerIdentity), "EquipInitialSpell")]
[HarmonyPrefix]
private static void Equip_Prefix(GameplayPlayerIdentity __instance, out bool __state)
{
__state = IsLocalOwner((NetworkBehaviour)(object)__instance);
if (__state)
{
context++;
}
}
[HarmonyPatch(typeof(GameplayPlayerIdentity), "EquipInitialSpell")]
[HarmonyPostfix]
private static void Equip_Postfix(bool __state)
{
if (__state)
{
context = Math.Max(0, context - 1);
}
}
[HarmonyPatch(typeof(PlayerSpell), "HasLifeStealOnSpell")]
[HarmonyPrefix]
private static void LifeSteal_Prefix(PlayerSpell __instance, out bool __state)
{
__state = IsLocalOwner((NetworkBehaviour)(object)__instance);
if (__state)
{
context++;
}
}
[HarmonyPatch(typeof(PlayerSpell), "HasLifeStealOnSpell")]
[HarmonyPostfix]
private static void LifeSteal_Postfix(bool __state)
{
if (__state)
{
context = Math.Max(0, context - 1);
}
}
[HarmonyPatch(typeof(StatButtonsPanel), "OnWizardButtonClicked")]
[HarmonyPrefix]
private static void WizardPanel_Prefix()
{
context++;
}
[HarmonyPatch(typeof(StatButtonsPanel), "OnWizardButtonClicked")]
[HarmonyPostfix]
private static void WizardPanel_Postfix()
{
context = Math.Max(0, context - 1);
}
private static void LogEquip(GameplayPlayerIdentity identity)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
try
{
CharacterResource character = identity.Character;
if ((Object)(object)character == (Object)null)
{
return;
}
SpellType? val = Spells.ChoiceFor(character.Id);
if (val.HasValue)
{
ManualLogSource log = Plugin.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(21, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Starting spell for ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<CharacterId>(character.Id);
((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<SpellType>(val.Value);
}
log.LogInfo(val2);
}
}
catch
{
}
}
}
}