using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("BossVSIntro")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Boss VS Intro")]
[assembly: AssemblyTitle("BossVSIntro")]
[assembly: AssemblyVersion("1.0.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 BossVSIntro
{
[BepInPlugin("com.scout.bossvsintro", "Boss VS Intro", "1.3.0")]
public class BossVSIntroPlugin : BaseUnityPlugin
{
public const string PluginGuid = "com.scout.bossvsintro";
public const string PluginName = "Boss VS Intro";
public const string PluginVersion = "1.3.0";
internal static BossVSIntroPlugin Instance;
internal static ManualLogSource Log;
internal static string ImagesRoot;
internal static string SoundsRoot;
internal static string TextRoot;
internal static string PluginDir;
private void Awake()
{
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
PluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
ImagesRoot = Path.Combine(PluginDir, "Images");
SoundsRoot = Path.Combine(PluginDir, "Sounds");
TextRoot = Path.Combine(PluginDir, "Text");
new Harmony("com.scout.bossvsintro").PatchAll();
Log.LogInfo((object)"Boss VS Intro v1.3.0 loaded.");
SceneManager.sceneLoaded += delegate
{
BossVSIntroPatch.ClearOutroWatch();
};
BossVSIntroPatch.BeginPreloadSounds();
}
private void Update()
{
BossVSIntroPatch.EnsureRunner();
}
}
internal static class VSConfig
{
public static float introCooldown = 5f;
public static float slideInDuration = 0.45f;
public static float vsPopDuration = 0.35f;
public static float vsStartScale = 3.5f;
public static float vsHeightFraction = 0.35f;
public static float shakeDuration = 0.4f;
public static float colorFadeDuration = 0.35f;
public static float shakeAmplitude = 38f;
public static float holdDuration = 1f;
public static float slideOutDuration = 0.4f;
public static float centerGap = -1920f;
public static string triggerSoundFile = "Trigger.wav";
public static float soundVolume = 1f;
public static float vsDelay = 1f;
public static string playerFileName = "Player.png";
public static string vsFileName = "VS.png";
public static string bossFolderName = "Bosses";
public static string bossFallbackName = "Default.png";
public static string backgroundFolderName = "Backgrounds";
public static string backgroundFallbackName = "Default.png";
public static string backgroundPlayerFolder = "Player";
public static string backgroundBossesFolder = "Bosses";
public static string playerTextFileName = "Player.txt";
public static string textFallbackName = "Default.txt";
public static float textFontSize = 72f;
public static float textYFraction = -0.32f;
public static float textSlideDuration = 0.35f;
public static float textOutlineWidth = 0.1f;
public static float positionTolerance = 6f;
public static float barVisibleTimeout = 5f;
public static string crossOutFileName = "CROSSEDOUT.png";
public static string iconFolderName = "Icons";
public static float iconHeightFraction = 1f;
public static float crossOutHeightFraction = 0.5f;
public static float outroCrossDelay = 0.5f;
public static float outroHoldDuration = 1f;
public static string ultrakilledTextFileName = "ULTRAKILLED.txt";
public static string objectDeathBosses = "1000_THR_DEFENCE_SYSTEM";
public static string earthmoverBossName = "1000_THR_EARTHMOVER";
public static string earthmoverStyleName = "RAISON D'ETRE";
public static bool logOutroWatch = false;
public static string audioTriggerOutros = "LEVEL_4_4|V2|Versus2Outro";
public static float outroTriggerDelay = 1f;
public static float outroBossTextX = 0f;
public static float outroBossTextY = -256f;
public static string outroSoundFile = "Outro.wav";
}
public class VSRunner : MonoBehaviour
{
private void Update()
{
BossVSIntroPatch.CheckOutroWatch();
BossVSIntroPatch.CheckAudioTrigger();
}
}
public class RectFollower : MonoBehaviour
{
public RectTransform target;
private RectTransform self;
private void Awake()
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
self = (RectTransform)((Component)this).transform;
}
private void LateUpdate()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)target != (Object)null && (Object)(object)self != (Object)null)
{
self.anchoredPosition = target.anchoredPosition;
}
}
}
[HarmonyPatch(typeof(BossHealthBarTemplate))]
public class BossVSIntroPatch
{
private class WatchedBoss
{
public Component eid;
public BossHealthBar bar;
public string bossName;
public Vector3 bossPos;
public string level;
public bool objectDeath;
}
private class TextSpec
{
public string title;
public bool hasPos;
public Vector2 pos;
public bool hasSize;
public float size;
public bool hasColor;
public Color color;
}
private static bool introPlaying;
private static float lastIntroTime = -9999f;
private static readonly List<WatchedBoss> watched = new List<WatchedBoss>();
private static bool outroPlaying;
private static Type eidType;
private static FieldInfo eidDeadField;
private static bool eidWarned;
private static bool frozeForCard;
private static float frozeAt;
private static float freezeCheckNext;
private static bool earthmoverArmed;
private static string earthmoverName;
private static Vector3 earthmoverPos;
private static bool audioArmed;
private static string audioBossName;
private static Vector3 audioBossPos;
private static string audioClip;
private static Canvas introCanvas;
private static AudioSource introAudio;
private static readonly Dictionary<string, Sprite> spriteCache = new Dictionary<string, Sprite>();
private static AudioClip triggerClip;
private static AudioClip outroClip;
private static MonoBehaviour runner;
private static float audioNextScan;
private static Type sceneHelperType;
private static readonly Dictionary<string, List<(int idx, Vector3 pos)>> EncounterMap = BuildEncounterMap();
private static TMP_FontAsset cachedFont;
private static readonly Dictionary<Sprite, Sprite> whiteCache = new Dictionary<Sprite, Sprite>();
private static MonoBehaviour Runner
{
get
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
if ((Object)(object)runner == (Object)null)
{
GameObject val = new GameObject("BossVSIntroRunner");
Object.DontDestroyOnLoad((Object)(object)val);
runner = (MonoBehaviour)(object)val.AddComponent<VSRunner>();
}
return runner;
}
}
public static void EnsureRunner()
{
MonoBehaviour val = Runner;
}
[HarmonyPostfix]
[HarmonyPatch("Initialize", new Type[]
{
typeof(BossHealthBar),
typeof(SliderLayer[])
})]
private static void InitializePostfix(BossHealthBarTemplate __instance, BossHealthBar bossBar, SliderLayer[] colorLayers)
{
if (!((Object)(object)__instance == (Object)null) && !((Object)(object)bossBar == (Object)null) && !string.IsNullOrEmpty(bossBar.bossName))
{
EnsureRunner();
Runner.StartCoroutine(WaitForBarThenTrigger(__instance, bossBar, bossBar.bossName));
}
}
private static IEnumerator WaitForBarThenTrigger(BossHealthBarTemplate template, BossHealthBar bossBar, string bossName)
{
if ((Object)(object)template == (Object)null)
{
yield break;
}
float deadline = Time.unscaledTime + VSConfig.barVisibleTimeout;
while (Time.unscaledTime < deadline)
{
if ((Object)(object)template == (Object)null)
{
yield break;
}
if (((Component)template).gameObject.activeInHierarchy)
{
break;
}
yield return null;
}
if ((Object)(object)template == (Object)null || !((Component)template).gameObject.activeInHierarchy)
{
yield break;
}
while (outroPlaying)
{
yield return null;
}
if (!introPlaying && !(Time.unscaledTime - lastIntroTime < VSConfig.introCooldown))
{
Vector3 bossPos = (((Object)(object)bossBar != (Object)null) ? ((Component)bossBar).transform.position : ((Component)template).transform.position);
if ((Object)(object)bossBar != (Object)null)
{
ArmOutroWatch(bossBar, bossName, bossPos);
}
Runner.StartCoroutine(PlayVSIntro(bossName, bossPos));
}
}
private static void ArmOutroWatch(BossHealthBar bossBar, string bossName, Vector3 bossPos)
{
//IL_0028: 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_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_024b: Unknown result type (might be due to invalid IL or missing references)
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
try
{
if (Sanitize(bossName) == Sanitize(VSConfig.earthmoverBossName))
{
earthmoverArmed = true;
earthmoverName = bossName;
earthmoverPos = bossPos;
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] armed '" + bossName + "' (earthmover / style bonus)"));
}
return;
}
string text = AudioTriggerClipFor(Sanitize(CurrentLevelName()), Sanitize(bossName));
if (text != null)
{
audioArmed = true;
audioBossName = bossName;
audioBossPos = bossPos;
audioClip = text;
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] armed '" + bossName + "' (sound '" + text + "')"));
}
return;
}
if (eidType == null)
{
eidType = AccessTools.TypeByName("EnemyIdentifier");
}
if (eidType != null && eidDeadField == null)
{
eidDeadField = eidType.GetField("dead", BindingFlags.Instance | BindingFlags.Public);
}
if (eidType == null || eidDeadField == null)
{
if (!eidWarned)
{
eidWarned = true;
BossVSIntroPlugin.Log.LogWarning((object)"Couldn't find EnemyIdentifier.dead");
}
return;
}
Component val = ((Component)bossBar).GetComponentInParent(eidType);
if ((Object)(object)val == (Object)null)
{
val = ((Component)bossBar).GetComponentInChildren(eidType);
}
if ((Object)(object)val == (Object)null)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogWarning((object)("[OutroWatch] '" + bossName + "' has NO EnemyIdentifier"));
}
return;
}
foreach (WatchedBoss item in watched)
{
if ((Object)(object)item.eid == (Object)(object)val)
{
return;
}
}
bool flag = IsObjectDeathBoss(bossName);
watched.Add(new WatchedBoss
{
eid = val,
bar = bossBar,
bossName = bossName,
bossPos = bossPos,
level = Sanitize(CurrentLevelName()),
objectDeath = flag
});
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)string.Format("[OutroWatch] armed '{0}' (watched, death signal: {1}). count={2}", bossName, flag ? "bar gone" : "dead flag", watched.Count));
}
}
catch (Exception ex)
{
BossVSIntroPlugin.Log.LogError((object)("Outro watch failed to arm: " + ex.Message));
}
}
private static bool IsObjectDeathBoss(string bossName)
{
string text = Sanitize(bossName);
string[] array = VSConfig.objectDeathBosses.Split(new char[1] { ',' });
foreach (string text2 in array)
{
if (Sanitize(text2.Trim()) == text)
{
return true;
}
}
return false;
}
public static void ClearOutroWatch()
{
watched.Clear();
earthmoverArmed = false;
audioArmed = false;
}
private static string AudioTriggerClipFor(string levelStem, string bossStem)
{
string[] array = VSConfig.audioTriggerOutros.Split(new char[1] { ',' });
foreach (string text in array)
{
string[] array2 = text.Split(new char[1] { '|' });
if (array2.Length == 3 && Sanitize(array2[0].Trim()) == levelStem && Sanitize(array2[1].Trim()) == bossStem)
{
return array2[2].Trim();
}
}
return null;
}
public static void CheckAudioTrigger()
{
//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
if (!audioArmed || Time.unscaledTime < audioNextScan)
{
return;
}
audioNextScan = Time.unscaledTime + 0.1f;
AudioSource[] array = Object.FindObjectsOfType<AudioSource>();
AudioSource[] array2 = array;
foreach (AudioSource val in array2)
{
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.clip == (Object)null) && val.isPlaying && ((Object)val.clip).name == audioClip)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] '" + audioBossName + "' sound '" + audioClip + "' started -> playing card"));
}
audioArmed = false;
Runner.StartCoroutine(OutroAfterDelay(audioBossName, audioBossPos));
break;
}
}
}
public static void OnStyleBonus(string styleName)
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
if (earthmoverArmed && !string.IsNullOrEmpty(styleName) && !(styleName != VSConfig.earthmoverStyleName))
{
earthmoverArmed = false;
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] '" + earthmoverName + "' style bonus -> playing card"));
}
Runner.StartCoroutine(OutroAfterDelay(earthmoverName, earthmoverPos));
}
}
public static void CheckOutroWatch()
{
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_0272: Unknown result type (might be due to invalid IL or missing references)
if (watched.Count == 0)
{
return;
}
string text = Sanitize(CurrentLevelName());
for (int num = watched.Count - 1; num >= 0; num--)
{
WatchedBoss watchedBoss = watched[num];
if (watchedBoss.level != text)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] dropped '" + watchedBoss.bossName + "' (level '" + watchedBoss.level + "' != '" + text + "')"));
}
watched.RemoveAt(num);
continue;
}
if (watchedBoss.objectDeath)
{
if ((Object)(object)watchedBoss.bar == (Object)null || !((Component)watchedBoss.bar).gameObject.activeInHierarchy)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] '" + watchedBoss.bossName + "' bar gone -> playing card"));
}
watched.RemoveAt(num);
Runner.StartCoroutine(OutroAfterDelay(watchedBoss.bossName, watchedBoss.bossPos));
}
continue;
}
if ((Object)(object)watchedBoss.eid == (Object)null)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] dropped '" + watchedBoss.bossName + "' (eid null)"));
}
watched.RemoveAt(num);
continue;
}
bool flag;
try
{
flag = (bool)eidDeadField.GetValue(watchedBoss.eid);
}
catch (Exception ex)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogWarning((object)("[OutroWatch] '" + watchedBoss.bossName + "' dead-read threw (" + ex.Message + ") — dropped"));
}
watched.RemoveAt(num);
continue;
}
if (flag)
{
if (VSConfig.logOutroWatch)
{
BossVSIntroPlugin.Log.LogInfo((object)("[OutroWatch] '" + watchedBoss.bossName + "' read dead=true -> playing card"));
}
watched.RemoveAt(num);
Runner.StartCoroutine(OutroAfterDelay(watchedBoss.bossName, watchedBoss.bossPos));
}
}
}
private static IEnumerator OutroAfterDelay(string bossName, Vector3 bossPos)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
float t = 0f;
while (t < VSConfig.outroTriggerDelay)
{
t += Time.unscaledDeltaTime;
yield return null;
}
while (introPlaying || outroPlaying)
{
yield return null;
}
outroPlaying = true;
yield return PlayOutro(bossName, bossPos);
}
public static void BeginPreloadSounds()
{
Runner.StartCoroutine(PreloadSounds());
}
private static IEnumerator PreloadSounds()
{
yield return LoadClip(Path.Combine(BossVSIntroPlugin.SoundsRoot, VSConfig.triggerSoundFile), delegate(AudioClip c)
{
triggerClip = c;
});
yield return LoadClip(Path.Combine(BossVSIntroPlugin.SoundsRoot, VSConfig.outroSoundFile), delegate(AudioClip c)
{
outroClip = c;
});
}
private static IEnumerator LoadClip(string fullPath, Action<AudioClip> onLoaded)
{
if (!File.Exists(fullPath))
{
BossVSIntroPlugin.Log.LogWarning((object)("Sound not found (splash will be silent for this one): " + fullPath));
onLoaded(null);
yield break;
}
AudioType type = GuessAudioType(fullPath);
UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip("file://" + fullPath, type);
try
{
yield return req.SendWebRequest();
if ((int)req.result != 1)
{
BossVSIntroPlugin.Log.LogError((object)("Failed to load sound '" + fullPath + "': " + req.error));
onLoaded(null);
yield break;
}
onLoaded(DownloadHandlerAudioClip.GetContent(req));
}
finally
{
((IDisposable)req)?.Dispose();
}
}
private static AudioType GuessAudioType(string path)
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: 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)
string text = Path.GetExtension(path).ToLowerInvariant();
string text2 = text;
if (!(text2 == ".ogg"))
{
if (text2 == ".mp3")
{
return (AudioType)13;
}
return (AudioType)20;
}
return (AudioType)14;
}
private static void PlaySound(AudioClip clip)
{
if (!((Object)(object)clip == (Object)null) && !((Object)(object)introAudio == (Object)null))
{
introAudio.PlayOneShot(clip, VSConfig.soundVolume);
}
}
private static string Sanitize(string name)
{
StringBuilder stringBuilder = new StringBuilder();
string text = name.ToUpperInvariant();
foreach (char c in text)
{
if (char.IsLetterOrDigit(c))
{
stringBuilder.Append(c);
}
else if (c == ' ' || c == '-' || c == '_')
{
stringBuilder.Append('_');
}
}
return stringBuilder.ToString();
}
public static string CurrentLevelName()
{
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
try
{
if (sceneHelperType == null)
{
sceneHelperType = AccessTools.TypeByName("SceneHelper");
}
if (sceneHelperType != null)
{
PropertyInfo property = sceneHelperType.GetProperty("CurrentScene", BindingFlags.Static | BindingFlags.Public);
if (property != null && property.GetValue(null) is string text && !string.IsNullOrEmpty(text))
{
return text;
}
FieldInfo field = sceneHelperType.GetField("CurrentScene", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.GetValue(null) is string text2 && !string.IsNullOrEmpty(text2))
{
return text2;
}
}
}
catch
{
}
Scene activeScene = SceneManager.GetActiveScene();
return ((Scene)(ref activeScene)).name;
}
private static Sprite ResolveBackgroundSprite(string sideFolder, string bossName, Vector3 bossPos)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
string text = Sanitize(bossName);
string text2 = Sanitize(CurrentLevelName());
string path = Path.Combine(BossVSIntroPlugin.ImagesRoot, VSConfig.backgroundFolderName, sideFolder);
int num = EncounterIndex(text2, text, bossPos);
List<string> list = new List<string>();
if (num >= 2)
{
list.Add(Path.Combine(path, text2, $"{text}_{num}.png"));
list.Add(Path.Combine(path, $"{text}_{num}.png"));
}
list.Add(Path.Combine(path, text2, text + ".png"));
list.Add(Path.Combine(path, text + ".png"));
list.Add(Path.Combine(path, text2 + ".png"));
list.Add(Path.Combine(path, text2, VSConfig.backgroundFallbackName));
list.Add(Path.Combine(path, VSConfig.backgroundFallbackName));
foreach (string item in list)
{
Sprite val = LoadSprite(item);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Sprite ResolveBossSprite(string bossName, Vector3 bossPos)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
string text = Sanitize(bossName);
string text2 = Sanitize(CurrentLevelName());
string path = Path.Combine(BossVSIntroPlugin.ImagesRoot, VSConfig.bossFolderName);
int num = EncounterIndex(text2, text, bossPos);
List<string> list = new List<string>();
if (num >= 2)
{
list.Add(Path.Combine(path, text2, $"{text}_{num}.png"));
list.Add(Path.Combine(path, $"{text}_{num}.png"));
}
list.Add(Path.Combine(path, text2, text + ".png"));
list.Add(Path.Combine(path, text + ".png"));
list.Add(Path.Combine(path, text2, VSConfig.bossFallbackName));
list.Add(Path.Combine(path, VSConfig.bossFallbackName));
foreach (string item in list)
{
Sprite val = LoadSprite(item);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Dictionary<string, List<(int, Vector3)>> BuildEncounterMap()
{
Dictionary<string, List<(int, Vector3)>> dictionary = new Dictionary<string, List<(int, Vector3)>>();
Add(dictionary, "LEVEL_0_5", "CERBERUS_GUARDIAN_OF_HELL", 1, 207.5f, -6.5f, 394.5f);
Add(dictionary, "LEVEL_0_5", "CERBERUS_GUARDIAN_OF_HELL", 2, 207.5f, -6.5f, 369.5f);
Add(dictionary, "LEVEL_1_E", "HIDEOUS_MASS", 1, 280.25f, 1.5f, 450.75f);
Add(dictionary, "LEVEL_1_E", "HIDEOUS_MASS", 2, 346f, 31f, 568f);
Add(dictionary, "LEVEL_4_4", "V2", 1, 117.5f, 661f, 263f);
Add(dictionary, "LEVEL_4_4", "V2", 2, 200f, 610.5f, 1150f);
Add(dictionary, "LEVEL_7_1", "SMINOTAUR", 1, -242.5f, -1f, 60.25f);
Add(dictionary, "LEVEL_7_1", "SMINOTAUR", 2, -225.5f, 95f, -414.75f);
return dictionary;
}
private static void Add(Dictionary<string, List<(int, Vector3)>> m, string level, string boss, int idx, float x, float y, float z)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
string key = level + "|" + boss;
if (!m.TryGetValue(key, out var value))
{
value = (m[key] = new List<(int, Vector3)>());
}
value.Add((idx, new Vector3(x, y, z)));
}
private static int EncounterIndex(string levelStem, string bossStem, Vector3 pos)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
string key = levelStem + "|" + bossStem;
if (!EncounterMap.TryGetValue(key, out List<(int, Vector3)> value))
{
return 1;
}
int num = -1;
float num2 = float.MaxValue;
foreach (var item in value)
{
float num3 = Vector3.Distance(pos, item.Item2);
if (num3 < num2)
{
num2 = num3;
(num, _) = item;
}
}
return (num <= 0 || !(num2 <= VSConfig.positionTolerance)) ? 1 : num;
}
private static Sprite LoadSprite(string fullPath)
{
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
if (spriteCache.TryGetValue(fullPath, out var value))
{
return value;
}
if (!File.Exists(fullPath))
{
return null;
}
try
{
byte[] array = File.ReadAllBytes(fullPath);
Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
ImageConversion.LoadImage(val, array);
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
spriteCache[fullPath] = val2;
return val2;
}
catch (Exception ex)
{
BossVSIntroPlugin.Log.LogError((object)("Failed to load image '" + fullPath + "': " + ex.Message));
return null;
}
}
private static Canvas GetOrCreateCanvas()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
if ((Object)(object)introCanvas != (Object)null)
{
return introCanvas;
}
GameObject val = new GameObject("BossVSIntroCanvas");
Object.DontDestroyOnLoad((Object)(object)val);
introCanvas = val.AddComponent<Canvas>();
introCanvas.renderMode = (RenderMode)0;
introCanvas.sortingOrder = 32767;
CanvasScaler val2 = val.AddComponent<CanvasScaler>();
val2.uiScaleMode = (ScaleMode)0;
val2.scaleFactor = 1f;
val.AddComponent<GraphicRaycaster>();
introAudio = val.AddComponent<AudioSource>();
introAudio.playOnAwake = false;
introAudio.spatialBlend = 0f;
introAudio.ignoreListenerPause = true;
return introCanvas;
}
private static string LoadText(string fullPath)
{
try
{
if (!File.Exists(fullPath))
{
return null;
}
string text = File.ReadAllText(fullPath).Trim();
return (text.Length == 0) ? null : text;
}
catch (Exception ex)
{
BossVSIntroPlugin.Log.LogError((object)("Failed to read text '" + fullPath + "': " + ex.Message));
return null;
}
}
private static TextSpec ResolvePlayerText()
{
return ParseTextFile(Path.Combine(BossVSIntroPlugin.TextRoot, VSConfig.playerTextFileName));
}
private static TextSpec ResolveEnemyText(string bossName, Vector3 bossPos)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
string text = Sanitize(bossName);
string text2 = Sanitize(CurrentLevelName());
string textRoot = BossVSIntroPlugin.TextRoot;
int num = EncounterIndex(text2, text, bossPos);
List<string> list = new List<string>();
if (num >= 2)
{
list.Add(Path.Combine(textRoot, text2, $"{text}_{num}.txt"));
list.Add(Path.Combine(textRoot, $"{text}_{num}.txt"));
}
list.Add(Path.Combine(textRoot, text2, text + ".txt"));
list.Add(Path.Combine(textRoot, text + ".txt"));
list.Add(Path.Combine(textRoot, text2, VSConfig.textFallbackName));
list.Add(Path.Combine(textRoot, VSConfig.textFallbackName));
foreach (string item in list)
{
TextSpec textSpec = ParseTextFile(item);
if (textSpec != null)
{
return textSpec;
}
}
return null;
}
private static TextSpec ParseTextFile(string fullPath)
{
//IL_0207: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
string text = LoadText(fullPath);
if (text == null)
{
return null;
}
TextSpec textSpec = new TextSpec();
string[] array = text.Split(new char[1] { '\n' });
foreach (string text2 in array)
{
string text3 = text2.Trim();
int num = text3.IndexOf(':');
if (num < 0)
{
continue;
}
string text4 = text3.Substring(0, num).Trim().ToLowerInvariant();
string text5 = text3.Substring(num + 1).Trim().Trim(new char[1] { '"' });
switch (text4)
{
case "title":
textSpec.title = text5;
break;
case "position":
{
if (TryVec2(text5, out var v))
{
textSpec.pos = v;
textSpec.hasPos = true;
}
break;
}
case "font size":
case "fontsize":
case "size":
{
if (float.TryParse(text5, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
{
textSpec.size = result;
textSpec.hasSize = true;
}
break;
}
case "color":
case "colour":
{
if (TryColor(text5, out var c))
{
textSpec.color = c;
textSpec.hasColor = true;
}
break;
}
}
}
return string.IsNullOrEmpty(textSpec.title) ? null : textSpec;
}
private static bool TryVec2(string s, out Vector2 v)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: 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)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
v = Vector2.zero;
string[] array = s.Split(new char[1] { ',' });
if (array.Length < 2)
{
return false;
}
if (float.TryParse(array[0].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result2))
{
v = new Vector2(result, result2);
return true;
}
return false;
}
private static bool TryColor(string s, out Color c)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
c = Color.white;
string[] array = s.Split(new char[1] { ',' });
if (array.Length < 3)
{
return false;
}
if (!byte.TryParse(array[0].Trim(), out var result) || !byte.TryParse(array[1].Trim(), out var result2) || !byte.TryParse(array[2].Trim(), out var result3))
{
return false;
}
byte result4 = byte.MaxValue;
if (array.Length >= 4)
{
byte.TryParse(array[3].Trim(), out result4);
}
c = Color32.op_Implicit(new Color32(result, result2, result3, result4));
return true;
}
private static TMP_FontAsset GetFont()
{
if ((Object)(object)cachedFont != (Object)null)
{
return cachedFont;
}
TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
if (array != null)
{
TMP_FontAsset[] array2 = array;
foreach (TMP_FontAsset val in array2)
{
if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf("VCR", StringComparison.OrdinalIgnoreCase) >= 0)
{
return cachedFont = val;
}
}
}
if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
{
return cachedFont = TMP_Settings.defaultFontAsset;
}
if (array != null && array.Length != 0)
{
cachedFont = array[0];
}
return cachedFont;
}
private static TextMeshProUGUI MakeText(Transform parent, string content, string name, float fontSize, Color color)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
val.transform.SetParent(parent, false);
TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
TMP_FontAsset font = GetFont();
if ((Object)(object)font != (Object)null)
{
((TMP_Text)val2).font = font;
}
((TMP_Text)val2).text = content;
((TMP_Text)val2).fontSize = fontSize;
((TMP_Text)val2).fontStyle = (FontStyles)1;
((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
((TMP_Text)val2).enableWordWrapping = false;
((TMP_Text)val2).overflowMode = (TextOverflowModes)0;
((Graphic)val2).color = color;
((Graphic)val2).raycastTarget = false;
if (VSConfig.textOutlineWidth > 0f)
{
Material fontMaterial = ((TMP_Text)val2).fontMaterial;
fontMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, VSConfig.textOutlineWidth);
}
RectTransform rectTransform = ((TMP_Text)val2).rectTransform;
Vector2 val3 = default(Vector2);
((Vector2)(ref val3))..ctor(0.5f, 0.5f);
rectTransform.pivot = val3;
Vector2 anchorMin = (rectTransform.anchorMax = val3);
rectTransform.anchorMin = anchorMin;
rectTransform.sizeDelta = new Vector2(fontSize * 12f, fontSize * 2f);
return val2;
}
private static Sprite WhiteSilhouette(Sprite src)
{
//IL_0063: 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)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: Expected O, but got Unknown
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)src == (Object)null)
{
return null;
}
if (whiteCache.TryGetValue(src, out var value))
{
return value;
}
Texture2D texture = src.texture;
Color32[] pixels = texture.GetPixels32();
for (int i = 0; i < pixels.Length; i++)
{
pixels[i] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, pixels[i].a);
}
Texture2D val = new Texture2D(((Texture)texture).width, ((Texture)texture).height, (TextureFormat)4, false);
val.SetPixels32(pixels);
val.Apply();
((Texture)val).filterMode = (FilterMode)1;
((Texture)val).wrapMode = (TextureWrapMode)1;
Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
whiteCache[src] = val2;
return val2;
}
private static Image MakeFlash(Image fighter, Sprite fighterSprite)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Expected O, but got Unknown
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: 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_0069: 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_0071: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("VS_Flash");
val.transform.SetParent(((Component)fighter).transform, false);
Image val2 = val.AddComponent<Image>();
val2.sprite = WhiteSilhouette(fighterSprite);
((Graphic)val2).raycastTarget = false;
val2.preserveAspect = true;
RectTransform rectTransform = ((Graphic)val2).rectTransform;
rectTransform.anchorMin = Vector2.zero;
rectTransform.anchorMax = Vector2.one;
Vector2 offsetMin = (rectTransform.offsetMax = Vector2.zero);
rectTransform.offsetMin = offsetMin;
SetFlashAlpha(val2, 0f);
return val2;
}
private static void SetFlashAlpha(Image flash, float a)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)flash == (Object)null))
{
((Graphic)flash).color = new Color(1f, 1f, 1f, a);
}
}
private static Sprite ResolveIconSprite(string bossName, Vector3 bossPos)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
string text = Sanitize(bossName);
string text2 = Sanitize(CurrentLevelName());
string path = Path.Combine(BossVSIntroPlugin.ImagesRoot, VSConfig.iconFolderName);
int num = EncounterIndex(text2, text, bossPos);
List<string> list = new List<string>();
if (num >= 2)
{
list.Add(Path.Combine(path, text2, $"{text}_{num}.png"));
list.Add(Path.Combine(path, $"{text}_{num}.png"));
}
list.Add(Path.Combine(path, text2, text + ".png"));
list.Add(Path.Combine(path, text + ".png"));
list.Add(Path.Combine(path, text2, VSConfig.bossFallbackName));
list.Add(Path.Combine(path, VSConfig.bossFallbackName));
foreach (string item in list)
{
Sprite val = LoadSprite(item);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
return null;
}
private static Vector2 ShakeOffset(float since)
{
//IL_0047: 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_001b: 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_004f: Unknown result type (might be due to invalid IL or missing references)
if (since < 0f || since >= VSConfig.shakeDuration)
{
return Vector2.zero;
}
float num = VSConfig.shakeAmplitude * (1f - since / VSConfig.shakeDuration);
return new Vector2(Random.Range(0f - num, num), Random.Range(0f - num, num));
}
private static IEnumerator PlayOutro(string bossName, Vector3 bossPos)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
outroPlaying = true;
Sprite iconSprite = ResolveIconSprite(bossName, bossPos);
Sprite crossSprite = LoadSprite(Path.Combine(BossVSIntroPlugin.ImagesRoot, VSConfig.crossOutFileName));
TextSpec bossSpec = ResolveEnemyText(bossName, bossPos);
TextSpec ultraSpec = ParseTextFile(Path.Combine(BossVSIntroPlugin.TextRoot, VSConfig.ultrakilledTextFileName));
if ((Object)(object)iconSprite == (Object)null)
{
BossVSIntroPlugin.Log.LogWarning((object)("Missing icon for '" + bossName + "' in Images/" + VSConfig.iconFolderName + "/ — kill card skipped."));
}
if ((Object)(object)crossSprite == (Object)null)
{
BossVSIntroPlugin.Log.LogWarning((object)("Missing Images/" + VSConfig.crossOutFileName + " — kill card skipped."));
}
if ((Object)(object)iconSprite == (Object)null || (Object)(object)crossSprite == (Object)null)
{
outroPlaying = false;
yield break;
}
float previousTimeScale = Time.timeScale;
Time.timeScale = 0f;
frozeForCard = true;
frozeAt = Time.unscaledTime;
Image iconImg = null;
Image crossImg = null;
TextMeshProUGUI bossTxt = null;
TextMeshProUGUI ultraTxt = null;
IEnumerator anim = AnimateOutro(iconSprite, crossSprite, bossSpec, ultraSpec, delegate(Image i)
{
iconImg = i;
}, delegate(Image i)
{
crossImg = i;
}, delegate(TextMeshProUGUI tx)
{
bossTxt = tx;
}, delegate(TextMeshProUGUI tx)
{
ultraTxt = tx;
});
while (true)
{
Time.timeScale = 0f;
object current;
try
{
if (!anim.MoveNext())
{
break;
}
current = anim.Current;
goto IL_025f;
}
catch (Exception ex)
{
Exception e = ex;
BossVSIntroPlugin.Log.LogError((object)$"Kill card threw, bailing safely: {e}");
}
break;
IL_025f:
yield return current;
}
if ((Object)(object)iconImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)iconImg).gameObject);
}
if ((Object)(object)crossImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)crossImg).gameObject);
}
if ((Object)(object)bossTxt != (Object)null)
{
Object.Destroy((Object)(object)((Component)bossTxt).gameObject);
}
if ((Object)(object)ultraTxt != (Object)null)
{
Object.Destroy((Object)(object)((Component)ultraTxt).gameObject);
}
Time.timeScale = previousTimeScale;
frozeForCard = false;
outroPlaying = false;
}
private static IEnumerator AnimateOutro(Sprite iconSprite, Sprite crossSprite, TextSpec bossSpec, TextSpec ultraSpec, Action<Image> outIcon, Action<Image> outCross, Action<TextMeshProUGUI> outBossTxt, Action<TextMeshProUGUI> outUltraTxt)
{
Canvas canvas = GetOrCreateCanvas();
float screenH = Screen.height;
float resScale = screenH / 1080f;
PlaySound(outroClip);
Image iconImg = MakeImage(((Component)canvas).transform, iconSprite, "VS_OutroIcon", screenH * VSConfig.iconHeightFraction);
Image crossImg = MakeImage(((Component)canvas).transform, crossSprite, "VS_OutroCross", screenH * VSConfig.crossOutHeightFraction);
outIcon(iconImg);
outCross(crossImg);
((Transform)((Graphic)crossImg).rectTransform).SetAsLastSibling();
RectTransform iconRT = ((Graphic)iconImg).rectTransform;
RectTransform crossRT = ((Graphic)crossImg).rectTransform;
float bossSize = ((bossSpec != null && bossSpec.hasSize) ? bossSpec.size : VSConfig.textFontSize) * resScale;
Vector2 bossTxtPos = new Vector2(VSConfig.outroBossTextX, VSConfig.outroBossTextY) * resScale;
TextMeshProUGUI bossTxt = null;
RectTransform bossTxtRT = null;
if (bossSpec != null)
{
bossTxt = MakeText(color: bossSpec.hasColor ? bossSpec.color : Color.white, parent: ((Component)canvas).transform, content: bossSpec.title, name: "VS_OutroBossText", fontSize: bossSize);
bossTxtRT = ((TMP_Text)bossTxt).rectTransform;
bossTxtRT.anchoredPosition = bossTxtPos;
((Component)bossTxt).gameObject.SetActive(false);
outBossTxt(bossTxt);
}
string ultraTitle = ((ultraSpec != null && !string.IsNullOrEmpty(ultraSpec.title)) ? ultraSpec.title : "ULTRAKILLED");
float ultraSize = ((ultraSpec != null && ultraSpec.hasSize) ? ultraSpec.size : VSConfig.textFontSize) * resScale;
Color ultraCol = ((ultraSpec != null && ultraSpec.hasColor) ? ultraSpec.color : Color.white);
Vector2 ultraPos = ((ultraSpec != null && ultraSpec.hasPos) ? (ultraSpec.pos * resScale) : (bossTxtPos + new Vector2(0f, 0f - bossSize * 1.25f)));
TextMeshProUGUI ultraTxt = MakeText(((Component)canvas).transform, ultraTitle, "VS_OutroKilledText", ultraSize, ultraCol);
RectTransform ultraTxtRT = ((TMP_Text)ultraTxt).rectTransform;
ultraTxtRT.anchoredPosition = ultraPos;
((Component)ultraTxt).gameObject.SetActive(false);
outUltraTxt(ultraTxt);
Vector2 iconBase = Vector2.zero;
Vector2 crossBase = Vector2.zero;
iconRT.anchoredPosition = iconBase;
crossRT.anchoredPosition = crossBase;
((Transform)iconRT).localScale = Vector3.one * VSConfig.vsStartScale;
((Transform)crossRT).localScale = Vector3.one * VSConfig.vsStartScale;
((Component)crossImg).gameObject.SetActive(false);
float t1 = VSConfig.vsPopDuration;
float t2 = t1 + VSConfig.outroCrossDelay;
float t3 = t2 + VSConfig.vsPopDuration;
float t4 = t3 + VSConfig.shakeDuration;
float t5 = t4 + VSConfig.outroHoldDuration;
float tEnd = t5 + VSConfig.slideOutDuration;
bool crossShown = false;
bool bossShown = false;
bool ultraShown = false;
float T = 0f;
while (T < tEnd)
{
T += Time.unscaledDeltaTime;
float ki = EaseOutCubic(Mathf.Clamp01(T / VSConfig.vsPopDuration));
((Transform)iconRT).localScale = Vector3.one * Mathf.LerpUnclamped(VSConfig.vsStartScale, 1f, ki);
if (!bossShown && T >= t1 && (Object)(object)bossTxt != (Object)null)
{
((Component)bossTxt).gameObject.SetActive(true);
bossShown = true;
}
if (T >= t2)
{
if (!crossShown)
{
((Component)crossImg).gameObject.SetActive(true);
crossShown = true;
}
float kc = EaseOutCubic(Mathf.Clamp01((T - t2) / VSConfig.vsPopDuration));
((Transform)crossRT).localScale = Vector3.one * Mathf.LerpUnclamped(VSConfig.vsStartScale, 1f, kc);
}
if (!ultraShown && T >= t3)
{
((Component)ultraTxt).gameObject.SetActive(true);
ultraShown = true;
}
Vector2 off = ShakeOffset(T - t1) + ShakeOffset(T - t3);
if (T >= t5)
{
float ko = EaseInCubic(Mathf.Clamp01((T - t5) / VSConfig.slideOutDuration));
off += new Vector2(0f, screenH * 1.2f * ko);
}
iconRT.anchoredPosition = iconBase + off;
crossRT.anchoredPosition = crossBase + off;
if ((Object)(object)bossTxtRT != (Object)null)
{
bossTxtRT.anchoredPosition = bossTxtPos + off;
}
ultraTxtRT.anchoredPosition = ultraPos + off;
yield return null;
}
}
private static Image MakeImage(Transform parent, Sprite sprite, string name, float targetHeight)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
val.transform.SetParent(parent, false);
Image val2 = val.AddComponent<Image>();
val2.sprite = sprite;
((Graphic)val2).raycastTarget = false;
val2.preserveAspect = true;
RectTransform rectTransform = ((Graphic)val2).rectTransform;
rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
rectTransform.pivot = new Vector2(0.5f, 0.5f);
float num = (float)((Texture)sprite.texture).width / (float)((Texture)sprite.texture).height;
rectTransform.sizeDelta = new Vector2(targetHeight * num, targetHeight);
rectTransform.anchoredPosition = Vector2.zero;
((Transform)rectTransform).localScale = Vector3.one;
return val2;
}
private static float EaseOutCubic(float x)
{
return 1f - Mathf.Pow(1f - x, 3f);
}
private static float EaseInCubic(float x)
{
return x * x * x;
}
private static IEnumerator PlayVSIntro(string bossName, Vector3 bossPos)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
introPlaying = true;
string playerPath = Path.Combine(BossVSIntroPlugin.ImagesRoot, VSConfig.playerFileName);
string vsPath = Path.Combine(BossVSIntroPlugin.ImagesRoot, VSConfig.vsFileName);
Sprite playerSprite = LoadSprite(playerPath);
Sprite vsSprite = LoadSprite(vsPath);
Sprite bossSprite = ResolveBossSprite(bossName, bossPos);
Sprite playerBgSprite = ResolveBackgroundSprite(VSConfig.backgroundPlayerFolder, bossName, bossPos);
Sprite enemyBgSprite = ResolveBackgroundSprite(VSConfig.backgroundBossesFolder, bossName, bossPos);
TextSpec playerText = ResolvePlayerText();
TextSpec enemyText = ResolveEnemyText(bossName, bossPos);
if ((Object)(object)playerSprite == (Object)null)
{
BossVSIntroPlugin.Log.LogWarning((object)("Missing player image: " + playerPath));
}
if ((Object)(object)vsSprite == (Object)null)
{
BossVSIntroPlugin.Log.LogWarning((object)("Missing VS image: " + vsPath));
}
if ((Object)(object)bossSprite == (Object)null)
{
BossVSIntroPlugin.Log.LogWarning((object)("Missing boss image for '" + bossName + "' (no level override, no generic, no Default.png)."));
}
if ((Object)(object)playerSprite == (Object)null || (Object)(object)vsSprite == (Object)null || (Object)(object)bossSprite == (Object)null)
{
introPlaying = false;
yield break;
}
lastIntroTime = Time.unscaledTime;
float previousTimeScale = Time.timeScale;
Time.timeScale = 0f;
frozeForCard = true;
frozeAt = Time.unscaledTime;
Image playerImg = null;
Image bossImg = null;
Image vsImg = null;
Image playerBgImg = null;
Image enemyBgImg = null;
TextMeshProUGUI playerTxt = null;
TextMeshProUGUI enemyTxt = null;
IEnumerator anim = AnimateCard(playerSprite, bossSprite, vsSprite, playerBgSprite, enemyBgSprite, playerText, enemyText, delegate(Image img)
{
playerImg = img;
}, delegate(Image img)
{
bossImg = img;
}, delegate(Image img)
{
vsImg = img;
}, delegate(Image img)
{
playerBgImg = img;
}, delegate(Image img)
{
enemyBgImg = img;
}, delegate(TextMeshProUGUI t)
{
playerTxt = t;
}, delegate(TextMeshProUGUI t)
{
enemyTxt = t;
});
while (true)
{
Time.timeScale = 0f;
object current;
try
{
if (!anim.MoveNext())
{
break;
}
current = anim.Current;
goto IL_0345;
}
catch (Exception ex)
{
Exception e = ex;
BossVSIntroPlugin.Log.LogError((object)$"Boss VS Intro splash threw, bailing safely: {e}");
}
break;
IL_0345:
yield return current;
}
if ((Object)(object)playerImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)playerImg).gameObject);
}
if ((Object)(object)bossImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)bossImg).gameObject);
}
if ((Object)(object)vsImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)vsImg).gameObject);
}
if ((Object)(object)playerBgImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)playerBgImg).gameObject);
}
if ((Object)(object)enemyBgImg != (Object)null)
{
Object.Destroy((Object)(object)((Component)enemyBgImg).gameObject);
}
if ((Object)(object)playerTxt != (Object)null)
{
Object.Destroy((Object)(object)((Component)playerTxt).gameObject);
}
if ((Object)(object)enemyTxt != (Object)null)
{
Object.Destroy((Object)(object)((Component)enemyTxt).gameObject);
}
Time.timeScale = previousTimeScale;
frozeForCard = false;
introPlaying = false;
}
private static IEnumerator AnimateCard(Sprite playerSprite, Sprite bossSprite, Sprite vsSprite, Sprite playerBgSprite, Sprite enemyBgSprite, TextSpec playerText, TextSpec enemyText, Action<Image> outPlayer, Action<Image> outBoss, Action<Image> outVs, Action<Image> outPlayerBg, Action<Image> outEnemyBg, Action<TextMeshProUGUI> outPlayerTxt, Action<TextMeshProUGUI> outEnemyTxt)
{
Canvas canvas = GetOrCreateCanvas();
PlaySound(triggerClip);
float screenW = Screen.width;
float screenH = Screen.height;
Image playerImg = MakeImage(((Component)canvas).transform, playerSprite, "VS_Player", screenH);
Image bossImg = MakeImage(((Component)canvas).transform, bossSprite, "VS_Boss", screenH);
Image vsImg = MakeImage(((Component)canvas).transform, vsSprite, "VS_Badge", screenH * VSConfig.vsHeightFraction);
((Graphic)playerImg).color = Color.black;
((Graphic)bossImg).color = Color.black;
Image playerFlash = MakeFlash(playerImg, playerSprite);
Image bossFlash = MakeFlash(bossImg, bossSprite);
outPlayer(playerImg);
outBoss(bossImg);
outVs(vsImg);
RectTransform playerRT = ((Graphic)playerImg).rectTransform;
RectTransform bossRT = ((Graphic)bossImg).rectTransform;
RectTransform vsRT = ((Graphic)vsImg).rectTransform;
float resScale = screenH / 1080f;
float halfGap = VSConfig.centerGap * resScale * 0.5f;
float playerHalfW = playerRT.sizeDelta.x * 0.5f;
float bossHalfW = bossRT.sizeDelta.x * 0.5f;
Vector2 playerStart = new Vector2(0f - screenW, 0f);
Vector2 bossStart = new Vector2(screenW, 0f);
Vector2 playerEnd = new Vector2(0f - (playerHalfW + halfGap), 0f);
Vector2 bossEnd = new Vector2(bossHalfW + halfGap, 0f);
playerRT.anchoredPosition = playerStart;
bossRT.anchoredPosition = bossStart;
vsRT.anchoredPosition = Vector2.zero;
((Transform)playerRT).SetAsLastSibling();
((Transform)bossRT).SetAsLastSibling();
((Transform)vsRT).SetAsLastSibling();
if ((Object)(object)playerBgSprite != (Object)null)
{
Image pbg = MakeImage(((Component)canvas).transform, playerBgSprite, "VS_PlayerBg", screenH);
((Graphic)pbg).rectTransform.anchoredPosition = playerStart;
((Transform)((Graphic)pbg).rectTransform).SetAsFirstSibling();
((Component)pbg).gameObject.AddComponent<RectFollower>().target = playerRT;
outPlayerBg(pbg);
}
if ((Object)(object)enemyBgSprite != (Object)null)
{
Image ebg = MakeImage(((Component)canvas).transform, enemyBgSprite, "VS_EnemyBg", screenH);
((Graphic)ebg).rectTransform.anchoredPosition = bossStart;
((Transform)((Graphic)ebg).rectTransform).SetAsFirstSibling();
((Component)ebg).gameObject.AddComponent<RectFollower>().target = bossRT;
outEnemyBg(ebg);
}
((Component)vsImg).gameObject.SetActive(false);
float resScaleTxt = screenH / 1080f;
float textY = screenH * VSConfig.textYFraction;
RectTransform playerTxtRT = null;
RectTransform enemyTxtRT = null;
Vector2 playerTxtStart = Vector2.zero;
Vector2 playerTxtEnd = Vector2.zero;
Vector2 enemyTxtStart = Vector2.zero;
Vector2 enemyTxtEnd = Vector2.zero;
if (playerText != null)
{
float size = (playerText.hasSize ? playerText.size : VSConfig.textFontSize) * resScaleTxt;
Color col = (playerText.hasColor ? playerText.color : Color.white);
playerTxtEnd = (Vector2)(playerText.hasPos ? (playerText.pos * resScaleTxt) : new Vector2(playerEnd.x, textY));
playerTxtStart = new Vector2(0f - screenW, playerTxtEnd.y);
TextMeshProUGUI t2 = MakeText(((Component)canvas).transform, playerText.title, "VS_PlayerText", size, col);
((TMP_Text)t2).rectTransform.anchoredPosition = playerTxtStart;
playerTxtRT = ((TMP_Text)t2).rectTransform;
outPlayerTxt(t2);
}
if (enemyText != null)
{
float size2 = (enemyText.hasSize ? enemyText.size : VSConfig.textFontSize) * resScaleTxt;
Color col2 = (enemyText.hasColor ? enemyText.color : Color.white);
enemyTxtEnd = (Vector2)(enemyText.hasPos ? (enemyText.pos * resScaleTxt) : new Vector2(bossEnd.x, textY));
enemyTxtStart = new Vector2(screenW, enemyTxtEnd.y);
TextMeshProUGUI t3 = MakeText(((Component)canvas).transform, enemyText.title, "VS_EnemyText", size2, col2);
((TMP_Text)t3).rectTransform.anchoredPosition = enemyTxtStart;
enemyTxtRT = ((TMP_Text)t3).rectTransform;
outEnemyTxt(t3);
}
float t4 = 0f;
while (t4 < VSConfig.slideInDuration)
{
t4 += Time.unscaledDeltaTime;
float k = EaseOutCubic(Mathf.Clamp01(t4 / VSConfig.slideInDuration));
playerRT.anchoredPosition = Vector2.LerpUnclamped(playerStart, playerEnd, k);
bossRT.anchoredPosition = Vector2.LerpUnclamped(bossStart, bossEnd, k);
yield return null;
}
playerRT.anchoredPosition = playerEnd;
bossRT.anchoredPosition = bossEnd;
t4 = 0f;
while (t4 < VSConfig.vsDelay)
{
t4 += Time.unscaledDeltaTime;
yield return null;
}
((Component)vsImg).gameObject.SetActive(true);
float popDuration = Mathf.Max(VSConfig.vsPopDuration, VSConfig.textSlideDuration);
t4 = 0f;
while (t4 < popDuration)
{
t4 += Time.unscaledDeltaTime;
float kv = EaseOutCubic(Mathf.Clamp01(t4 / VSConfig.vsPopDuration));
((Transform)vsRT).localScale = Vector3.one * Mathf.LerpUnclamped(VSConfig.vsStartScale, 1f, kv);
float kt = EaseOutCubic(Mathf.Clamp01(t4 / VSConfig.textSlideDuration));
if ((Object)(object)playerTxtRT != (Object)null)
{
playerTxtRT.anchoredPosition = Vector2.LerpUnclamped(playerTxtStart, playerTxtEnd, kt);
}
if ((Object)(object)enemyTxtRT != (Object)null)
{
enemyTxtRT.anchoredPosition = Vector2.LerpUnclamped(enemyTxtStart, enemyTxtEnd, kt);
}
yield return null;
}
((Transform)vsRT).localScale = Vector3.one;
if ((Object)(object)playerTxtRT != (Object)null)
{
playerTxtRT.anchoredPosition = playerTxtEnd;
}
if ((Object)(object)enemyTxtRT != (Object)null)
{
enemyTxtRT.anchoredPosition = enemyTxtEnd;
}
((Graphic)playerImg).color = Color.white;
((Graphic)bossImg).color = Color.white;
SetFlashAlpha(playerFlash, 1f);
SetFlashAlpha(bossFlash, 1f);
t4 = 0f;
while (t4 < VSConfig.shakeDuration)
{
t4 += Time.unscaledDeltaTime;
float decay = 1f - Mathf.Clamp01(t4 / VSConfig.shakeDuration);
float amp = VSConfig.shakeAmplitude * decay;
playerRT.anchoredPosition = playerEnd + new Vector2(Random.Range(0f - amp, amp), Random.Range(0f - amp, amp));
bossRT.anchoredPosition = bossEnd + new Vector2(Random.Range(0f - amp, amp), Random.Range(0f - amp, amp));
float flash = 1f - Mathf.Clamp01(t4 / VSConfig.colorFadeDuration);
SetFlashAlpha(playerFlash, flash);
SetFlashAlpha(bossFlash, flash);
yield return null;
}
playerRT.anchoredPosition = playerEnd;
bossRT.anchoredPosition = bossEnd;
SetFlashAlpha(playerFlash, 0f);
SetFlashAlpha(bossFlash, 0f);
t4 = 0f;
while (t4 < VSConfig.holdDuration)
{
t4 += Time.unscaledDeltaTime;
yield return null;
}
Vector2 vsUpEnd = new Vector2(0f, screenH);
t4 = 0f;
while (t4 < VSConfig.slideOutDuration)
{
t4 += Time.unscaledDeltaTime;
float k2 = EaseInCubic(Mathf.Clamp01(t4 / VSConfig.slideOutDuration));
playerRT.anchoredPosition = Vector2.LerpUnclamped(playerEnd, playerStart, k2);
bossRT.anchoredPosition = Vector2.LerpUnclamped(bossEnd, bossStart, k2);
vsRT.anchoredPosition = Vector2.LerpUnclamped(Vector2.zero, vsUpEnd, k2);
if ((Object)(object)playerTxtRT != (Object)null)
{
playerTxtRT.anchoredPosition = Vector2.LerpUnclamped(playerTxtEnd, playerTxtStart, k2);
}
if ((Object)(object)enemyTxtRT != (Object)null)
{
enemyTxtRT.anchoredPosition = Vector2.LerpUnclamped(enemyTxtEnd, enemyTxtStart, k2);
}
yield return null;
}
}
}
[HarmonyPatch(typeof(AddStylePoints), "Activate")]
public class EarthmoverStylePatch
{
private static void Postfix(AddStylePoints __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
BossVSIntroPatch.OnStyleBonus(__instance.styleName);
}
}
}
}