Decompiled source of FUNKIN IS FUEL v1.0.0
plugins/FunkinIsFuel.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PluginConfig.API; using PluginConfig.API.Decorators; using PluginConfig.API.Fields; using UnityEngine; using UnityEngine.Audio; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyVersion("0.0.0.0")] namespace RapBattle; internal class BfSprite { private struct AnimDef { public string Prefix; public Vector2 Offset; public bool Loop; public AnimDef(string prefix, float x, float y, bool loop) { //IL_000a: 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) Prefix = prefix; Offset = new Vector2(x, y); Loop = loop; } } private static readonly Dictionary<string, AnimDef> Defs = new Dictionary<string, AnimDef> { { "idle", new AnimDef("BF idle dance", -5f, 0f, loop: false) }, { "singLEFT", new AnimDef("BF NOTE LEFT", 12f, -6f, loop: false) }, { "singDOWN", new AnimDef("BF NOTE DOWN", -10f, -50f, loop: false) }, { "singUP", new AnimDef("BF NOTE UP", -29f, 27f, loop: false) }, { "singRIGHT", new AnimDef("BF NOTE RIGHT", -38f, -7f, loop: false) }, { "singLEFTmiss", new AnimDef("BF NOTE LEFT MISS", 12f, 24f, loop: false) }, { "singDOWNmiss", new AnimDef("BF NOTE DOWN MISS", -11f, -19f, loop: false) }, { "singUPmiss", new AnimDef("BF NOTE UP MISS", -29f, 27f, loop: false) }, { "singRIGHTmiss", new AnimDef("BF NOTE RIGHT MISS", -30f, 21f, loop: false) }, { "hey", new AnimDef("BF HEY!!", 7f, 4f, loop: false) }, { "hit", new AnimDef("BF hit", 0f, 0f, loop: false) }, { "dodge", new AnimDef("boyfriend dodge", 0f, 0f, loop: false) }, { "attack", new AnimDef("boyfriend attack", 0f, 0f, loop: false) }, { "preAttack", new AnimDef("bf pre attack", 0f, 0f, loop: false) }, { "scared", new AnimDef("BF idle shaking", -4f, 0f, loop: true) }, { "firstDeath", new AnimDef("BF dies", 37f, 11f, loop: false) }, { "deathLoop", new AnimDef("BF Dead Loop", 37f, 5f, loop: true) } }; private static readonly string[] SingNames = new string[4] { "singLEFT", "singDOWN", "singUP", "singRIGHT" }; private static Atlas atlas; private static Material material; private static string triedFolder; public GameObject Go; public float Height; private Mesh mesh; private float k; private Vector2 anchor; private string anim = "idle"; private float animStart; private float holdUntil; private bool flipped; private bool dead; private readonly Vector3[] verts = (Vector3[])(object)new Vector3[4]; private readonly Vector2[] uvs = (Vector2[])(object)new Vector2[4]; public Vector3 Center => Go.transform.position + Vector3.up * Height * 0.5f; private static bool Load() { //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown if (triedFolder == SongLibrary.FunkinFolder) { return atlas != null; } triedFolder = SongLibrary.FunkinFolder; string text = Path.Combine(Path.Combine(Path.Combine(Path.Combine(SongLibrary.FunkinFolder, "assets"), "shared"), "images"), "characters"); atlas = Atlas.Load(Path.Combine(text, "BOYFRIEND.png"), Path.Combine(text, "BOYFRIEND.xml")); if (atlas == null || atlas.Anim("BF idle dance") == null) { RapBattlePlugin.Log.LogWarning((object)("Boyfriend's sprite sheet wasn't found in " + text)); atlas = null; return false; } try { atlas.Texture.Compress(false); atlas.Texture.Apply(false, true); } catch (Exception) { } Shader val = Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Transparent"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Transparent Cutout"); } material = new Material(val); material.mainTexture = (Texture)(object)atlas.Texture; ((Object)material).hideFlags = (HideFlags)32; return true; } public static BfSprite Create(Vector3 feet, float height) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) if (!Load()) { return null; } BfSprite bfSprite = new BfSprite(); bfSprite.Height = height; bfSprite.Go = new GameObject("Rap Battle Boyfriend"); bfSprite.Go.transform.position = feet; bfSprite.mesh = new Mesh(); ((Object)bfSprite.mesh).name = "Boyfriend"; bfSprite.mesh.MarkDynamic(); bfSprite.Go.AddComponent<MeshFilter>().sharedMesh = bfSprite.mesh; MeshRenderer val = bfSprite.Go.AddComponent<MeshRenderer>(); ((Renderer)val).sharedMaterial = material; ((Renderer)val).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val).receiveShadows = false; AtlasFrame atlasFrame = atlas.Frame("BF idle dance", 0); AnimDef animDef = Defs["idle"]; float num = 0f - animDef.Offset.x + atlasFrame.OffX; float num2 = 0f - animDef.Offset.y + atlasFrame.OffY; bfSprite.anchor = new Vector2(num + atlasFrame.W * 0.5f, num2 + atlasFrame.H); bfSprite.k = height / Mathf.Max(1f, atlasFrame.H); bfSprite.mesh.vertices = bfSprite.verts; bfSprite.mesh.uv = bfSprite.uvs; bfSprite.mesh.triangles = new int[6] { 0, 2, 1, 2, 3, 1 }; bfSprite.Play("idle"); return bfSprite; } public void Play(string name) { if (!dead || !(name != "deathLoop")) { if (!Defs.ContainsKey(name) || atlas.Anim(Defs[name].Prefix) == null) { name = "idle"; } anim = name; animStart = Time.unscaledTime; } } public void Sing(int lane, float now, float holdMs, float stepMs) { Play(SingNames[lane]); holdUntil = now + holdMs + stepMs * 4f; } public void Hold(int lane, float now, float stepMs) { if (anim != SingNames[lane]) { Play(SingNames[lane]); } holdUntil = Mathf.Max(holdUntil, now + stepMs * 2f); } public void Miss(int lane, float now, float stepMs) { Play(SingNames[lane] + "miss"); holdUntil = now + stepMs * 5f; } public void Hey(float now, float holdMs) { Play("hey"); holdUntil = now + holdMs; } public void Hurt(float now, float holdMs) { Play("hit"); holdUntil = now + holdMs; } public void Dodge(float now, float holdMs) { Play("dodge"); holdUntil = now + holdMs; } public void Attack(float now, float holdMs) { Play("attack"); holdUntil = now + holdMs; } public void Scared(float now, float holdMs) { Play("scared"); holdUntil = now + holdMs; } public void Die() { Play("firstDeath"); dead = true; holdUntil = float.MaxValue; } public void Beat(int beat, float now) { if (!dead && now > holdUntil && beat % 2 == 0) { Play("idle"); } } public void Tick(float now, Camera cam, Vector3 enemy) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Go == (Object)null || atlas == null) { return; } if (!dead && anim != "idle" && now > holdUntil && anim != "scared") { Play("idle"); } if (anim == "scared" && now > holdUntil) { Play("idle"); } if ((Object)(object)cam != (Object)null) { Vector3 val = Go.transform.position - ((Component)cam).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { Go.transform.rotation = Quaternion.LookRotation(val, Vector3.up); } Vector3 val2 = cam.WorldToScreenPoint(Go.transform.position); Vector3 val3 = cam.WorldToScreenPoint(enemy); if (val2.z > 0f && val3.z > 0f) { flipped = val3.x > val2.x + 5f; } } string text = anim; if (flipped) { if (text.StartsWith("singLEFT")) { text = "singRIGHT" + text.Substring(8); } else if (text.StartsWith("singRIGHT")) { text = "singLEFT" + text.Substring(9); } } AnimDef animDef = Defs[text]; List<AtlasFrame> list = atlas.Anim(animDef.Prefix); if (list == null || list.Count == 0) { return; } int num = (int)((Time.unscaledTime - animStart) * 24f); if (animDef.Loop) { num %= list.Count; } else if (num >= list.Count) { num = list.Count - 1; if (anim == "firstDeath") { anim = "deathLoop"; animStart = Time.unscaledTime; } } AtlasFrame atlasFrame = list[num]; float num2 = 0f - animDef.Offset.x + atlasFrame.OffX; float num3 = 0f - animDef.Offset.y + atlasFrame.OffY; float num4 = (num2 - anchor.x) * k; float num5 = (num2 + atlasFrame.W - anchor.x) * k; float num6 = (anchor.y - (num3 + atlasFrame.H)) * k; float num7 = (anchor.y - num3) * k; if (flipped) { num4 = 0f - num4; num5 = 0f - num5; } ref Vector3 reference = ref verts[0]; reference = new Vector3(num4, num6, 0f); ref Vector3 reference2 = ref verts[1]; reference2 = new Vector3(num5, num6, 0f); ref Vector3 reference3 = ref verts[2]; reference3 = new Vector3(num4, num7, 0f); ref Vector3 reference4 = ref verts[3]; reference4 = new Vector3(num5, num7, 0f); ref Vector2 reference5 = ref uvs[0]; reference5 = new Vector2(((Rect)(ref atlasFrame.Uv)).xMin, ((Rect)(ref atlasFrame.Uv)).yMin); ref Vector2 reference6 = ref uvs[1]; reference6 = new Vector2(((Rect)(ref atlasFrame.Uv)).xMax, ((Rect)(ref atlasFrame.Uv)).yMin); ref Vector2 reference7 = ref uvs[2]; reference7 = new Vector2(((Rect)(ref atlasFrame.Uv)).xMin, ((Rect)(ref atlasFrame.Uv)).yMax); ref Vector2 reference8 = ref uvs[3]; reference8 = new Vector2(((Rect)(ref atlasFrame.Uv)).xMax, ((Rect)(ref atlasFrame.Uv)).yMax); mesh.vertices = verts; mesh.uv = uvs; mesh.RecalculateBounds(); } public void Destroy() { if ((Object)(object)Go != (Object)null) { Object.Destroy((Object)(object)Go); } if ((Object)(object)mesh != (Object)null) { Object.Destroy((Object)(object)mesh); } Go = null; } } internal class NoteData { public float Time; public int Lane; public float Length; public string Kind; public bool Player; public bool Avoid; public bool Hit; public bool Missed; public bool Holding; public bool Dropped; public bool HoldDone; } internal class EventData { public float Time; public string Name; public JToken Value; } internal class Conductor { private struct Change { public float Time; public float Bpm; public float Beat; } private readonly List<Change> changes = new List<Change>(); public Conductor(List<float> times, List<float> bpms) { List<KeyValuePair<float, float>> list = new List<KeyValuePair<float, float>>(); for (int i = 0; i < times.Count && i < bpms.Count; i++) { if (bpms[i] > 0f) { list.Add(new KeyValuePair<float, float>(times[i], bpms[i])); } } if (list.Count == 0) { list.Add(new KeyValuePair<float, float>(0f, 100f)); } list.Sort((KeyValuePair<float, float> a, KeyValuePair<float, float> b) => a.Key.CompareTo(b.Key)); float num = 0f; Change item = default(Change); for (int num2 = 0; num2 < list.Count; num2++) { if (num2 > 0) { num += (list[num2].Key - list[num2 - 1].Key) * list[num2 - 1].Value / 60000f; } item.Time = ((num2 == 0) ? Math.Min(0f, list[num2].Key) : list[num2].Key); item.Bpm = list[num2].Value; item.Beat = num; changes.Add(item); } } private Change At(float ms) { Change result = changes[0]; for (int i = 1; i < changes.Count && !(changes[i].Time > ms); i++) { result = changes[i]; } return result; } public float BeatAt(float ms) { Change change = At(ms); return change.Beat + (ms - change.Time) * change.Bpm / 60000f; } public float MsAtBeat(float beat) { Change change = changes[0]; for (int i = 1; i < changes.Count && !(changes[i].Beat > beat); i++) { change = changes[i]; } return change.Time + (beat - change.Beat) * 60000f / change.Bpm; } public float BpmAt(float ms) { return At(ms).Bpm; } public float CrochetAt(float ms) { return 60000f / At(ms).Bpm; } public float StepAt(float ms) { return 15000f / At(ms).Bpm; } } internal class ChartData { public SongEntry Song; public string Difficulty; public float ScrollSpeed = 1f; public List<NoteData> Notes = new List<NoteData>(); public List<EventData> Events = new List<EventData>(); public Conductor Conductor; public float LastNoteTime; public int PlayerNoteCount; public HashSet<string> EventNames = new HashSet<string>(); } internal static class ChartLoader { private static readonly string[] DifficultyOrder = new string[5] { "hard", "normal", "easy", "erect", "nightmare" }; private static readonly string[] HardestFirst = new string[5] { "nightmare", "erect", "hard", "normal", "easy" }; private static readonly string[] AvoidKindWords = new string[8] { "hell", "death", "hurt", "mine", "bomb", "glitch", "poison", "danger" }; internal static ChartData Load(SongEntry song, string preferred, Random rng, out string error) { //IL_0297: Unknown result type (might be due to invalid IL or missing references) error = null; JObject val = JObject.Parse(File.ReadAllText(song.ChartPath)); JToken obj = val["notes"]; JObject val2 = (JObject)(object)((obj is JObject) ? obj : null); if (val2 == null) { error = "chart has no notes"; return null; } List<string> list = new List<string>(); foreach (JProperty item2 in val2.Properties()) { JToken value = item2.Value; JArray val3 = (JArray)(object)((value is JArray) ? value : null); if (val3 == null) { continue; } int num = 0; foreach (JToken item3 in val3) { if ((int)SongLibrary.Num(item3[(object)"d"], 0f) % 8 < 4) { num++; } } if (num >= 16) { list.Add(item2.Name); } } if (list.Count == 0) { error = "no difficulty with enough player notes"; return null; } string text = null; if (preferred == "random") { text = list[rng.Next(list.Count)]; } if (preferred == "hardest") { string[] hardestFirst = HardestFirst; foreach (string name in hardestFirst) { text = Find(list, name); if (text != null) { break; } } } if (text == null) { text = Find(list, preferred); } int num2 = 0; while (text == null && num2 < DifficultyOrder.Length) { text = Find(list, DifficultyOrder[num2]); num2++; } if (text == null) { text = list[0]; } ChartData chartData = new ChartData(); chartData.Song = song; chartData.Difficulty = text; chartData.Conductor = new Conductor(song.BpmTimes, song.Bpms); JToken obj2 = val["scrollSpeed"]; JObject val4 = (JObject)(object)((obj2 is JObject) ? obj2 : null); if (val4 != null) { JToken val5 = val4[text] ?? val4["default"]; if (val5 == null) { using IEnumerator<JProperty> enumerator3 = val4.Properties().GetEnumerator(); if (enumerator3.MoveNext()) { JProperty current3 = enumerator3.Current; val5 = current3.Value; } } chartData.ScrollSpeed = SongLibrary.Num(val5, 1f); } else if (val["scrollSpeed"] != null) { chartData.ScrollSpeed = SongLibrary.Num(val["scrollSpeed"], 1f); } if (chartData.ScrollSpeed <= 0.1f) { chartData.ScrollSpeed = 1f; } HashSet<long> hashSet = new HashSet<long>(); foreach (JToken item4 in (JArray)val2[text]) { NoteData noteData = new NoteData(); noteData.Time = SongLibrary.Num(item4[(object)"t"], 0f); int num3 = (int)SongLibrary.Num(item4[(object)"d"], 0f) % 8; if (num3 < 0) { num3 += 8; } noteData.Lane = num3 % 4; noteData.Player = num3 < 4; noteData.Length = Math.Max(0f, SongLibrary.Num(item4[(object)"l"], 0f)); if (noteData.Length < 60f) { noteData.Length = 0f; } noteData.Kind = SongLibrary.Str(item4[(object)"k"], "") ?? ""; noteData.Avoid = IsAvoidKind(noteData.Kind); long item = ((long)Math.Round(noteData.Time) << 4) | (uint)num3; if (hashSet.Add(item)) { chartData.Notes.Add(noteData); if (noteData.Player && !noteData.Avoid) { chartData.PlayerNoteCount++; } chartData.LastNoteTime = Math.Max(chartData.LastNoteTime, noteData.Time + noteData.Length); } } chartData.Notes.Sort((NoteData a, NoteData b) => a.Time.CompareTo(b.Time)); JToken obj3 = val["events"]; JArray val6 = (JArray)(object)((obj3 is JArray) ? obj3 : null); if (val6 != null) { foreach (JToken item5 in val6) { EventData eventData = new EventData(); eventData.Time = SongLibrary.Num(item5[(object)"t"], 0f); eventData.Name = SongLibrary.Str(item5[(object)"e"], ""); eventData.Value = item5[(object)"v"]; if (eventData.Name.Length != 0) { chartData.Events.Add(eventData); chartData.EventNames.Add(eventData.Name); } } } return chartData; } private static string Find(List<string> list, string name) { foreach (string item in list) { if (string.Equals(item, name, StringComparison.OrdinalIgnoreCase)) { return item; } } return null; } internal static bool IsAvoidKind(string kind) { if (string.IsNullOrEmpty(kind)) { return false; } string text = kind.ToLowerInvariant(); string[] avoidKindWords = AvoidKindWords; foreach (string value in avoidKindWords) { if (text.Contains(value)) { return true; } } return false; } } internal static class ConfigMenu { internal const string PluginConfiguratorGuid = "com.eternalUnion.pluginConfigurator"; internal static void Build() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) PluginConfigurator val = PluginConfigurator.Create("FUNKIN' IS FUEL", "funkinisfuel.ultrakill"); ConfigPanel rootPanel = val.rootPanel; new ConfigHeader(rootPanel, "Mic", 24); AddKey(rootPanel, "Throw mic", RapBattlePlugin.MicKey); AddKey(rootPanel, "Pose maker", RapBattlePlugin.PoseEditorKey); AddKey(rootPanel, "Mic menu", RapBattlePlugin.MicMenuKey); AddBool(rootPanel, "Show the mic on the HUD", RapBattlePlugin.ShowMicHud); AddString(rootPanel, "Who raps for you (V1 / Boyfriend / Both)", RapBattlePlugin.PlayerCharacter); AddString(rootPanel, "Sick/Good popups (Notes / Center / Off)", RapBattlePlugin.RatingsPosition); AddFloat(rootPanel, "Boss intensity", RapBattlePlugin.BossIntensity, 0f, 2f); AddBool(rootPanel, "Other enemies dance", RapBattlePlugin.CrowdDance); AddInt(rootPanel, "Mics per level (0 = unlimited)", RapBattlePlugin.MicsPerLevel, 0, 20); new ConfigHeader(rootPanel, "Songs", 24); AddString(rootPanel, "FNF folder", RapBattlePlugin.FunkinPath); AddBool(rootPanel, "Base game songs", RapBattlePlugin.IncludeBaseGame); AddBool(rootPanel, "Mod songs", RapBattlePlugin.IncludeMods); AddString(rootPanel, "Excluded song ids", RapBattlePlugin.ExcludedSongs); AddString(rootPanel, "Difficulty (easy/normal/hard/erect/nightmare/random)", RapBattlePlugin.Difficulty); new ConfigHeader(rootPanel, "Notes", 24); string[] array = new string[4] { "Left", "Down", "Up", "Right" }; for (int i = 0; i < 4; i++) { AddKey(rootPanel, array[i], RapBattlePlugin.LaneKeys[i]); } for (int j = 0; j < 4; j++) { AddKey(rootPanel, array[j] + " (alt)", RapBattlePlugin.LaneKeys[j + 4]); } AddBool(rootPanel, "Ghost tapping", RapBattlePlugin.GhostTapping); AddBool(rootPanel, "Downscroll", RapBattlePlugin.Downscroll); AddBool(rootPanel, "Middlescroll", RapBattlePlugin.Middlescroll); AddFloat(rootPanel, "Scroll speed multiplier", RapBattlePlugin.ScrollSpeedMultiplier, 0.5f, 3f); AddFloat(rootPanel, "Audio offset (ms)", RapBattlePlugin.AudioOffsetMs, -300f, 300f); AddFloat(rootPanel, "Song volume", RapBattlePlugin.SongVolume, 0f, 1f); new ConfigHeader(rootPanel, "Battle", 24); AddInt(rootPanel, "Damage when you lose (100 = death)", RapBattlePlugin.LoseDamage, 0, 200); AddFloat(rootPanel, "Boss damage when you win (%)", RapBattlePlugin.BossWinDamagePercent, 0f, 100f); AddFloat(rootPanel, "Enemy health drain per note", RapBattlePlugin.OpponentHealthDrain, 0f, 0.05f); AddFloat(rootPanel, "Attacks per minute", RapBattlePlugin.AttacksPerMinute, 0f, 12f); AddBool(rootPanel, "Song mechanics become attacks", RapBattlePlugin.ChartAttacks); AddFloat(rootPanel, "Attack damage", RapBattlePlugin.AttackDamage, 0f, 2f); AddFloat(rootPanel, "Parry heal", RapBattlePlugin.ParryHeal, 0f, 2f); AddFloat(rootPanel, "Parry/dodge window (ms)", RapBattlePlugin.AttackWindowMs, 60f, 400f); new ConfigHeader(rootPanel, "Camera & events", 24); AddFloat(rootPanel, "Battle FOV", RapBattlePlugin.BattleFov, 30f, 100f); AddFloat(rootPanel, "Camera bop", RapBattlePlugin.CameraBopIntensity, 0f, 3f); AddBool(rootPanel, "Remix events into every song", RapBattlePlugin.RemixEvents); AddBool(rootPanel, "Screen flashes", RapBattlePlugin.ScreenFlashes); AddBool(rootPanel, "Show V1 on stage", RapBattlePlugin.ShowV1); AddBool(rootPanel, "Verbose log", RapBattlePlugin.DebugLog); } private static string FieldGuid(ConfigEntryBase entry) { return (entry.Definition.Section + "." + entry.Definition.Key).ToLowerInvariant(); } private static void AddBool(ConfigPanel panel, string label, ConfigEntry<bool> entry) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown BoolField field = new BoolField(panel, label, FieldGuid((ConfigEntryBase)(object)entry), entry.Value, false); field.postValueChangeEvent += (PostBoolValueChangeEvent)delegate(bool value) { entry.Value = value; }; entry.SettingChanged += delegate { if (field.value != entry.Value) { field.value = entry.Value; } }; } private static void AddFloat(ConfigPanel panel, string label, ConfigEntry<float> entry, float min, float max) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown FloatField field = new FloatField(panel, label, FieldGuid((ConfigEntryBase)(object)entry), entry.Value, min, max, true, false); field.postValueChangeEvent += (PostFloatValueChangeEvent)delegate(float value) { entry.Value = value; }; entry.SettingChanged += delegate { if (field.value != entry.Value) { field.value = entry.Value; } }; } private static void AddInt(ConfigPanel panel, string label, ConfigEntry<int> entry, int min, int max) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown IntField field = new IntField(panel, label, FieldGuid((ConfigEntryBase)(object)entry), entry.Value, min, max, true, false); field.postValueChangeEvent += (PostIntValueChangeEvent)delegate(int value) { entry.Value = value; }; entry.SettingChanged += delegate { if (field.value != entry.Value) { field.value = entry.Value; } }; } private static void AddString(ConfigPanel panel, string label, ConfigEntry<string> entry) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown StringField field = new StringField(panel, label, FieldGuid((ConfigEntryBase)(object)entry), entry.Value, true, false); field.postValueChangeEvent += (PostStringValueChangeEvent)delegate(string value) { entry.Value = value; }; entry.SettingChanged += delegate { if (field.value != entry.Value) { field.value = entry.Value; } }; } private static void AddKey(ConfigPanel panel, string label, ConfigEntry<KeyCode> entry) { //IL_0021: 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) //IL_0031: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown KeyCodeField field = new KeyCodeField(panel, label, FieldGuid((ConfigEntryBase)(object)entry), entry.Value, false); field.postValueChangeEvent += (PostKeyCodeValueChangeEvent)delegate(KeyCode value) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) entry.Value = value; }; entry.SettingChanged += delegate { //IL_0006: 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_0024: Unknown result type (might be due to invalid IL or missing references) if (field.value != entry.Value) { field.value = entry.Value; } }; } } internal static class Ease { internal static readonly Func<float, float> Linear = (float t) => t; internal static Func<float, float> Get(string name) { if (string.IsNullOrEmpty(name)) { return Linear; } string text = name.Trim(); string text2 = text.ToLowerInvariant(); switch (text2) { case "linear": case "classic": case "instant": return Linear; default: { string text3 = "InOut"; string text4 = text2; if (text2.EndsWith("inout")) { text3 = "InOut"; text4 = text2.Substring(0, text2.Length - 5); } else if (text2.EndsWith("out")) { text3 = "Out"; text4 = text2.Substring(0, text2.Length - 3); } else if (text2.EndsWith("in")) { text3 = "In"; text4 = text2.Substring(0, text2.Length - 2); } Func<float, float> ein = In(text4); if (ein == null) { return Linear; } if (text4 == "smoothstep" || text4 == "smootherstep") { Func<float, float> io = ((text4 == "smoothstep") ? ((Func<float, float>)((float t) => t * t * (3f - 2f * t))) : ((Func<float, float>)((float t) => t * t * t * (t * (t * 6f - 15f) + 10f)))); if (text3 == "In") { return (float t) => 2f * io(t * 0.5f); } if (text3 == "Out") { return (float t) => 2f * io(t * 0.5f + 0.5f) - 1f; } return io; } if (text3 == "In") { return ein; } if (text3 == "Out") { return (float t) => 1f - ein(1f - t); } return (float t) => (!(t < 0.5f)) ? (1f - ein((1f - t) * 2f) * 0.5f) : (ein(t * 2f) * 0.5f); } } } internal static string Combine(string ease, string dir) { if (string.IsNullOrEmpty(ease)) { return "linear"; } if (string.IsNullOrEmpty(dir)) { return ease; } string text = ease.ToLowerInvariant(); switch (text) { case "classic": case "instant": case "linear": return ease; default: if (text.EndsWith("in") || text.EndsWith("out")) { return ease; } return ease + dir; } } private static Func<float, float> In(string family) { switch (family) { case "quad": return (float t) => t * t; case "cube": case "cubic": return (float t) => t * t * t; case "quart": return (float t) => t * t * t * t; case "quint": return (float t) => t * t * t * t * t; case "sine": return (float t) => 1f - Mathf.Cos(t * (float)Math.PI * 0.5f); case "expo": return (float t) => (!(t <= 0f)) ? Mathf.Pow(2f, 10f * (t - 1f)) : 0f; case "circ": return (float t) => 1f - Mathf.Sqrt(Mathf.Max(0f, 1f - t * t)); case "back": return (float t) => t * t * (2.70158f * t - 1.70158f); case "elastic": return (float t) => (t <= 0f || t >= 1f) ? t : ((0f - Mathf.Pow(2f, 10f * (t - 1f))) * Mathf.Sin((t - 1.075f) * ((float)Math.PI * 2f) / 0.3f)); case "bounce": return (float t) => 1f - BounceOut(1f - t); case "smoothstep": case "smootherstep": return Linear; default: return null; } } private static float BounceOut(float t) { if (t < 0.36363637f) { return 7.5625f * t * t; } if (t < 0.72727275f) { t -= 0.54545456f; return 7.5625f * t * t + 0.75f; } if (t < 0.90909094f) { t -= 0.8181818f; return 7.5625f * t * t + 0.9375f; } t -= 21f / 22f; return 7.5625f * t * t + 63f / 64f; } } internal class FloatTween { private float from; private float to; private float t0; private float dur; private Func<float, float> ease = Ease.Linear; public float Target => to; public FloatTween(float value) { from = (to = value); } public void Set(float value) { from = (to = value); dur = 0f; } public void To(float target, float now, float durationMs, Func<float, float> curve) { from = Value(now); to = target; t0 = now; dur = Mathf.Max(0f, durationMs); ease = curve ?? Ease.Linear; } public float Value(float now) { if (dur <= 0f || now >= t0 + dur) { return to; } if (now <= t0) { return from; } return from + (to - from) * ease((now - t0) / dur); } } internal static class EventMaker { internal static void AddGenerated(ChartData chart, List<EventData> into, Random rng, bool remix, float endMs) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Expected O, but got Unknown //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Expected O, but got Unknown //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Expected O, but got Unknown //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Expected O, but got Unknown //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Expected O, but got Unknown //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Expected O, but got Unknown //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Expected O, but got Unknown //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Expected O, but got Unknown //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Expected O, but got Unknown //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Expected O, but got Unknown //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Expected O, but got Unknown //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0461: Expected O, but got Unknown //IL_045c: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Expected O, but got Unknown //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04cd: Expected O, but got Unknown //IL_0501: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Expected O, but got Unknown //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Expected O, but got Unknown //IL_0542: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Expected O, but got Unknown //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Expected O, but got Unknown //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Expected O, but got Unknown //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Expected O, but got Unknown //IL_0582: Unknown result type (might be due to invalid IL or missing references) //IL_058c: Expected O, but got Unknown //IL_061c: Unknown result type (might be due to invalid IL or missing references) //IL_0622: Expected O, but got Unknown //IL_0638: Unknown result type (might be due to invalid IL or missing references) //IL_063e: Expected O, but got Unknown //IL_0640: Unknown result type (might be due to invalid IL or missing references) //IL_064a: Expected O, but got Unknown //IL_0679: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Expected O, but got Unknown //IL_068d: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Expected O, but got Unknown //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_069f: Expected O, but got Unknown //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Expected O, but got Unknown //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_06e9: Expected O, but got Unknown //IL_06eb: Unknown result type (might be due to invalid IL or missing references) //IL_06f5: Expected O, but got Unknown //IL_0725: Unknown result type (might be due to invalid IL or missing references) //IL_072b: Expected O, but got Unknown //IL_073a: Unknown result type (might be due to invalid IL or missing references) //IL_0740: Expected O, but got Unknown //IL_074d: Unknown result type (might be due to invalid IL or missing references) //IL_0753: Expected O, but got Unknown //IL_0755: Unknown result type (might be due to invalid IL or missing references) //IL_075f: Expected O, but got Unknown //IL_078e: Unknown result type (might be due to invalid IL or missing references) //IL_0794: Expected O, but got Unknown //IL_07a2: Unknown result type (might be due to invalid IL or missing references) //IL_07a8: Expected O, but got Unknown //IL_07b5: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Expected O, but got Unknown //IL_07bd: Unknown result type (might be due to invalid IL or missing references) //IL_07c7: Expected O, but got Unknown //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Expected O, but got Unknown //IL_05cf: Unknown result type (might be due to invalid IL or missing references) //IL_05d5: Expected O, but got Unknown //IL_05e2: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Expected O, but got Unknown //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05f4: Expected O, but got Unknown Conductor conductor = chart.Conductor; float num = conductor.BeatAt(endMs); if (!chart.EventNames.Contains("FocusCamera")) { int num2 = -1; for (int i = 0; (float)(i * 4) < num; i++) { float num3 = conductor.MsAtBeat(i * 4); float num4 = conductor.MsAtBeat(i * 4 + 4); int num5 = 0; int num6 = 0; foreach (NoteData note in chart.Notes) { if (!(note.Time < num3)) { if (note.Time >= num4) { break; } if (note.Player) { num5++; } else { num6++; } } } if (num5 != 0 || num6 != 0) { int num7 = ((num5 <= num6) ? 1 : 0); if (num7 != num2) { num2 = num7; into.Add(Make(num3, "FocusCamera", (JToken)new JObject((object)new JProperty("char", (object)num7)))); } } } } if (!remix) { return; } string[] array = new string[9] { "flash", "shake", "punch", "sway", "lights", "hey", "bop", "glitch", "zoom" }; for (float num8 = 16f; num8 + 16f <= num; num8 += 16f) { float num9 = conductor.MsAtBeat(num8); bool flag = false; foreach (NoteData note2 in chart.Notes) { if (note2.Time >= num9 && note2.Time < conductor.MsAtBeat(num8 + 16f)) { flag = true; break; } } if (!flag || rng.NextDouble() < 0.25) { continue; } switch (array[rng.Next(array.Length)]) { case "flash": into.Add(Make(num9, "MFFlash", (JToken)new JObject(new object[3] { (object)new JProperty("color", (object)"#FFFFFF"), (object)new JProperty("duration", (object)4), (object)new JProperty("strength", (object)0.35) }))); break; case "shake": into.Add(Make(num9, "MFShake", (JToken)new JObject(new object[2] { (object)new JProperty("intensity", (object)0.004), (object)new JProperty("duration", (object)6) }))); break; case "punch": { for (int j = 0; j < 4; j++) { into.Add(Make(conductor.MsAtBeat(num8 + (float)(j * 4)), "__ZoomPunch", (JToken)new JValue(0.06))); } break; } case "sway": into.Add(Make(num9, "MFStrumFX", (JToken)new JObject(new object[3] { (object)new JProperty("mode", (object)"sway"), (object)new JProperty("amount", (object)0.35), (object)new JProperty("speed", (object)0.5) }))); into.Add(Make(conductor.MsAtBeat(num8 + 15f), "MFStrumFX", (JToken)new JObject((object)new JProperty("mode", (object)"off")))); break; case "lights": { string[] array2 = new string[5] { "#FF6D43FF", "#FFFF43A1", "#FF43FFD2", "#FFFFE943", "#FF8A43FF" }; into.Add(Make(num9, "sserafimPulseLights", (JToken)new JObject(new object[3] { (object)new JProperty("enabled", (object)true), (object)new JProperty("colors", (object)new JArray(new object[2] { array2[rng.Next(array2.Length)], array2[rng.Next(array2.Length)] })), (object)new JProperty("intensities", (object)new JArray(new object[2] { 0.6, 0.8 })) }))); into.Add(Make(conductor.MsAtBeat(num8 + 15.5f), "sserafimPulseLights", (JToken)new JObject((object)new JProperty("enabled", (object)false)))); break; } case "hey": into.Add(Make(conductor.MsAtBeat(num8 + 14f), "PlayAnimation", (JToken)new JObject(new object[2] { (object)new JProperty("target", (object)((rng.Next(2) == 0) ? "bf" : "dad")), (object)new JProperty("anim", (object)"hey") }))); break; case "bop": into.Add(Make(num9, "SetCameraBop", (JToken)new JObject(new object[2] { (object)new JProperty("rate", (object)1), (object)new JProperty("intensity", (object)1.5) }))); into.Add(Make(conductor.MsAtBeat(num8 + 8f), "SetCameraBop", (JToken)new JObject(new object[2] { (object)new JProperty("rate", (object)4), (object)new JProperty("intensity", (object)1) }))); break; case "glitch": into.Add(Make(num9, "MFGlitch", (JToken)new JObject(new object[2] { (object)new JProperty("intensity", (object)0.4), (object)new JProperty("duration", (object)4) }))); break; case "zoom": into.Add(Make(num9, "ZoomCamera", (JToken)new JObject(new object[3] { (object)new JProperty("zoom", (object)1.25), (object)new JProperty("duration", (object)16), (object)new JProperty("ease", (object)"expoOut") }))); into.Add(Make(conductor.MsAtBeat(num8 + 8f), "ZoomCamera", (JToken)new JObject(new object[3] { (object)new JProperty("zoom", (object)1), (object)new JProperty("duration", (object)8), (object)new JProperty("ease", (object)"quadInOut") }))); break; } } } private static EventData Make(float t, string name, JToken value) { EventData eventData = new EventData(); eventData.Time = t; eventData.Name = name; eventData.Value = value; return eventData; } } internal static class EventRunner { internal static void Run(RapBattle b, EventData e) { //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_0727: Unknown result type (might be due to invalid IL or missing references) //IL_0759: Unknown result type (might be due to invalid IL or missing references) //IL_075e: Unknown result type (might be due to invalid IL or missing references) //IL_0775: Unknown result type (might be due to invalid IL or missing references) //IL_0945: Unknown result type (might be due to invalid IL or missing references) //IL_098a: Unknown result type (might be due to invalid IL or missing references) //IL_0a38: Unknown result type (might be due to invalid IL or missing references) //IL_0a3d: Unknown result type (might be due to invalid IL or missing references) //IL_0a86: Unknown result type (might be due to invalid IL or missing references) //IL_0c43: Unknown result type (might be due to invalid IL or missing references) //IL_0c48: Unknown result type (might be due to invalid IL or missing references) //IL_0d91: Unknown result type (might be due to invalid IL or missing references) //IL_0e26: Unknown result type (might be due to invalid IL or missing references) //IL_0836: Unknown result type (might be due to invalid IL or missing references) //IL_09aa: Unknown result type (might be due to invalid IL or missing references) //IL_09a3: Unknown result type (might be due to invalid IL or missing references) //IL_0906: Unknown result type (might be due to invalid IL or missing references) //IL_09af: Unknown result type (might be due to invalid IL or missing references) //IL_09b3: Unknown result type (might be due to invalid IL or missing references) //IL_09b5: Unknown result type (might be due to invalid IL or missing references) //IL_0af8: Unknown result type (might be due to invalid IL or missing references) //IL_0afd: Unknown result type (might be due to invalid IL or missing references) //IL_0b02: Unknown result type (might be due to invalid IL or missing references) //IL_05d3: Unknown result type (might be due to invalid IL or missing references) //IL_05cc: Unknown result type (might be due to invalid IL or missing references) JToken value = e.Value; float stepMs = b.StepMs; float songPos = b.SongPos; BattleStage stage = b.Stage; BattleHud hud = b.Hud; switch (e.Name) { case "FocusCamera": { float x = 0f; float y = 0f; float num6 = 4f; string ease = "CLASSIC"; int character; if (value is JObject) { character = (int)Num(value, "char", 0f); x = Num(value, "x", 0f); y = Num(value, "y", 0f); num6 = Num(value, "duration", 4f); ease = Ease.Combine(Str(value, "ease", "CLASSIC"), Str(value, "easeDir", null)); } else { character = (int)SongLibrary.Num(value, 0f); } stage.Focus(character, x, y, num6 * stepMs, ease, songPos); break; } case "ZoomCamera": { float value2 = Num(value, "zoom", 1f); float num7 = Num(value, "duration", 4f); string ease2 = Ease.Combine(Str(value, "ease", "linear"), Str(value, "easeDir", null)); stage.Zoom(value2, num7 * stepMs, ease2, songPos); break; } case "SetCameraBop": b.SetCameraBop(Mathf.RoundToInt(Num(value, "rate", 4f)), Num(value, "intensity", 1f)); break; case "ScrollSpeed": { float num = Num(value, "scroll", 1f); float num2 = (Bool(value, "absolute", fallback: false) ? (num * RapBattlePlugin.ScrollSpeedMultiplier.Value) : (b.ChartScrollSpeed * num)); float num3 = Num(value, "duration", 4f) * stepMs; string text2 = Ease.Combine(Str(value, "ease", "linear"), Str(value, "easeDir", null)); b.SetScrollSpeed(Mathf.Clamp(num2, 0.3f, 6f), (text2.ToUpperInvariant() == "INSTANT") ? 0f : num3, Ease.Get(text2)); break; } case "PlayAnimation": { string t3 = Str(value, "target", "bf").ToLowerInvariant(); string text4 = Str(value, "anim", "").ToLowerInvariant(); Poser poser = (IsPlayer(t3) ? b.V1Poser : (IsEnemy(t3) ? b.EnemyPoser : null)); poser?.Special(songPos, stepMs * 6f); if (IsPlayer(t3) && b.Bf != null) { b.Bf.Hey(songPos, stepMs * 6f); } if (poser == null && (!IsPlayer(t3) || b.Bf == null)) { stage.Bop(0.03f); } if (text4.Contains("hey") || text4.Contains("cheer")) { hud.Banner("HEY!", IsEnemy(t3) ? BattleHud.EnemyColor : BattleHud.V1Color, 0.6f); } break; } case "SetTargetBopSpeed": { string t2 = Str(value, "target", "").ToLowerInvariant(); float danceEvery = Mathf.Max(1f, Num(value, "rate", 2f)); if (IsPlayer(t2) && b.V1Poser != null) { b.V1Poser.DanceEvery = danceEvery; } else if (IsEnemy(t2)) { b.EnemyPoser.DanceEvery = danceEvery; } break; } case "__ZoomPunch": stage.Bop(SongLibrary.Num(value, 0.05f)); hud.HudBop += 0.03f; break; case "MFShake": stage.Shake(Num(value, "intensity", 0.01f), Num(value, "duration", 4f) * stepMs / 1000f); break; case "sserafimGuitarVibration": stage.Shake(0.004f, Num(value, "duration", 0.5f)); break; case "sserafimKick": stage.Bop(0.05f); stage.Shake(0.006f, 0.15f); break; case "MFFlash": hud.Flash(ParseColor(Str(value, "color", "#FFFFFF"), Color.white), Num(value, "duration", 4f) * stepMs / 1000f, Num(value, "strength", 0.8f)); break; case "sserafimFlash": hud.Flash(Color.white, Num(value, "duration", 1f), 0.8f); break; case "RemnantsSNES": hud.Flash(ParseColor(Str(value, "color", "RED"), Color.red), 0.5f, 0.5f); break; case "changeStage": case "PlayExplVideo": case "TankmanAscendsEvent": hud.Flash(Color.white, 0.6f, 0.7f); stage.Bop(0.06f); break; case "MFGlitch": if (Str(value, "mode", "burst") == "ambient") { hud.Glitch(9999f, Num(value, "intensity", 0.3f) * 0.5f); } else { hud.Glitch(Num(value, "duration", 4f) * stepMs / 1000f, Num(value, "intensity", 0.6f)); } break; case "MFInvert": { string text3 = Str(value, "mode", "pulse"); if (!(text3 == "off")) { hud.Flash(new Color(0.4f, 1f, 0.95f), Num(value, "duration", 4f) * stepMs / 1000f, 0.55f); hud.Glitch(Num(value, "duration", 4f) * stepMs / 1000f, 0.3f); } break; } case "MFLights": Darken(hud, Str(value, "mode", "normal") switch { "dim" => 0.35f, "spotlight" => 0.82f, "blackout" => 0.96f, "dark" => 0.6f, _ => 0f, }, Num(value, "duration", 4f) * stepMs, songPos, Color.black); break; case "sserafimDark": Darken(hud, Mathf.Clamp01(Num(value, "amount", 0.5f)) * 0.8f, Num(value, "duration", 0.5f) * 1000f, songPos, Color.black); break; case "sserafimLights": Darken(hud, Mathf.Clamp01(1f - Num(value, "amount", 1f)) * 0.7f, Num(value, "duration", 0.5f) * 1000f, songPos, Color.black); break; case "RemnantsOverlay": { Color darkColor = (Bool(value, "white", fallback: false) ? Color.white : Color.black); hud.DarkColor = darkColor; hud.Dark.Set(Mathf.Clamp01(Num(value, "startOpacity", 1f))); hud.Dark.To(Mathf.Clamp01(Num(value, "endOpacity", 0f)), songPos, Num(value, "duration", 16f) * stepMs, Ease.Get(Ease.Combine(Str(value, "ease", "linear"), Str(value, "easeDir", null)))); break; } case "blackIn": case "cutsceneVideoOut": hud.DarkColor = Color.black; hud.Dark.Set(1f); hud.Dark.To(0f, songPos, stepMs * 8f, Ease.Get("quadOut")); break; case "fadeStart": case "cutsceneVideo": Darken(hud, 0.85f, stepMs * 8f, songPos, Color.black); break; case "sserafimPulseLights": { hud.PulseOn = Bool(value, "enabled", fallback: true); JArray val = Arr(value, "colors"); if (val != null && ((JContainer)val).Count > 0) { hud.PulseColors = (Color[])(object)new Color[((JContainer)val).Count]; for (int i = 0; i < ((JContainer)val).Count; i++) { ref Color reference = ref hud.PulseColors[i]; reference = ParseColor(SongLibrary.Str(val[i], "#FFFFFF"), Color.white); } } JArray val2 = Arr(value, "intensities"); if (val2 != null && ((JContainer)val2).Count > 0) { hud.PulseIntensities = new float[((JContainer)val2).Count]; for (int j = 0; j < ((JContainer)val2).Count; j++) { hud.PulseIntensities[j] = SongLibrary.Num(val2[j], 0.6f); } } break; } case "HazierGarcelloVignetteEvent": hud.Vignette = (Bool(value, "isActive", fallback: true) ? Mathf.Clamp(Num(value, "strength", 20f) / 30f, 0.2f, 0.9f) : 0f); break; case "MFHud": { float num4 = Num(value, "duration", 4f) * stepMs; float num5 = Mathf.Clamp01(Num(value, "alpha", 1f)); if (num4 <= 10f) { hud.HudAlpha.Set(num5); } else { hud.HudAlpha.To(num5, songPos, num4, Ease.Get("quadInOut")); } break; } case "MFLyrics": hud.Lyrics(Str(value, "text", ""), ParseColor(Str(value, "color", "#FFFFFF"), Color.white), Num(value, "duration", 16f) * stepMs / 1000f, Str(value, "style", "normal") == "glitch"); break; case "MFStrumFX": { string text = Str(value, "mode", "off"); hud.SwayAmount = ((text == "off" || text == "none") ? 0f : Num(value, "amount", 1f)); hud.SwaySpeed = Num(value, "speed", 1f); break; } case "MFStrumSwap": hud.Swap.To((hud.Swap.Target > 0.5f) ? 0f : 1f, songPos, Num(value, "duration", 8f) * stepMs, Ease.Get("quadInOut")); break; case "MFScrollFlip": hud.Flip.To((hud.Flip.Target > 0.5f) ? 0f : 1f, songPos, Num(value, "duration", 4f) * stepMs, Ease.Get("quadInOut")); break; case "SkillIssue": hud.Banner("SKILL ISSUE", new Color(1f, 0.3f, 0.3f), 1.5f); break; case "SetHealthIcon": stage.Bop(0.02f); break; case "MFHealthDrain": b.SetDrain(2f * Num(value, "amount", 0f) / 100f, Num(value, "floor", 15f) / 100f); break; case "HP Gremlin": b.Gremlin(0.35f, Mathf.Max(0.5f, SongLibrary.Num(Get(value, "value2"), 1.5f))); hud.Banner("HP GREMLIN!", new Color(0.6f, 1f, 0.4f), 1.2f); break; case "MFCharAlpha": { string t = Str(value, "target", "dad").ToLowerInvariant(); bool hidden = Num(value, "alpha", 1f) < 0.5f; (IsPlayer(t) ? b.V1Poser : (IsEnemy(t) ? b.EnemyPoser : null))?.SetHidden(hidden); break; } default: stage.Bop(0.025f); hud.HudBop += 0.015f; b.LogUnknownEvent(e.Name); break; case "sawKB": case "MFShatter": break; } } private static void Darken(BattleHud hud, float amount, float durationMs, float now, Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) hud.DarkColor = color; if (durationMs <= 10f) { hud.Dark.Set(amount); } else { hud.Dark.To(amount, now, durationMs, Ease.Get("quadInOut")); } } private static bool IsPlayer(string t) { switch (t) { default: return t == "0"; case "bf": case "boyfriend": case "player": return true; } } private static bool IsEnemy(string t) { switch (t) { default: return t == "1"; case "dad": case "opponent": case "enemy": return true; } } private static JToken Get(JToken v, string key) { JObject val = (JObject)(object)((v is JObject) ? v : null); if (val == null) { return null; } return val[key]; } private static float Num(JToken v, string key, float fallback) { return SongLibrary.Num(Get(v, key), fallback); } private static string Str(JToken v, string key, string fallback) { return SongLibrary.Str(Get(v, key), fallback); } private static bool Bool(JToken v, string key, bool fallback) { return SongLibrary.Bool(Get(v, key), fallback); } private static JArray Arr(JToken v, string key) { JToken obj = Get(v, key); return (JArray)(object)((obj is JArray) ? obj : null); } internal static Color ParseColor(string s, Color fallback) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: 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_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(s)) { return fallback; } string text = s.Trim(); switch (text.ToUpperInvariant()) { case "RED": return Color.red; case "GREEN": return Color.green; case "BLUE": return new Color(0.2f, 0.4f, 1f); case "WHITE": return Color.white; case "BLACK": return Color.black; case "YELLOW": return Color.yellow; case "PURPLE": return new Color(0.6f, 0.2f, 1f); case "PINK": return new Color(1f, 0.4f, 0.75f); case "CYAN": return Color.cyan; case "ORANGE": return new Color(1f, 0.55f, 0.1f); default: { if (text.StartsWith("#")) { text = text.Substring(1); } else if (text.StartsWith("0x") || text.StartsWith("0X")) { text = text.Substring(2); } if (!uint.TryParse(text, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { return fallback; } if (text.Length == 6) { result |= 0xFF000000u; } return new Color((float)((result >> 16) & 0xFF) / 255f, (float)((result >> 8) & 0xFF) / 255f, (float)(result & 0xFF) / 255f, 1f); } } } } internal class AtlasFrame { public Rect Uv; public float W; public float H; public float OffX; public float OffY; public float FrameW; public float FrameH; } internal class Atlas { public Texture2D Texture; private readonly Dictionary<string, List<AtlasFrame>> anims = new Dictionary<string, List<AtlasFrame>>(); private static readonly Regex SubTexture = new Regex("<SubTexture\\s+([^>]*?)/?>", RegexOptions.Compiled); private static readonly Regex Attr = new Regex("(\\w+)\\s*=\\s*\"([^\"]*)\"", RegexOptions.Compiled); private static readonly Regex Spaces = new Regex("\\s+", RegexOptions.Compiled); public static Atlas Load(string png, string xml) { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) Texture2D val = FnfAssets.LoadTexture(png); if ((Object)(object)val == (Object)null || !File.Exists(xml)) { return null; } Atlas atlas = new Atlas(); atlas.Texture = val; Dictionary<string, SortedList<int, AtlasFrame>> dictionary = new Dictionary<string, SortedList<int, AtlasFrame>>(); foreach (Match item in SubTexture.Matches(File.ReadAllText(xml))) { Dictionary<string, string> dictionary2 = new Dictionary<string, string>(); foreach (Match item2 in Attr.Matches(item.Groups[1].Value)) { dictionary2[item2.Groups[1].Value] = item2.Groups[2].Value; } if (dictionary2.TryGetValue("name", out var value)) { AtlasFrame atlasFrame = new AtlasFrame(); float num = F(dictionary2, "x"); float num2 = F(dictionary2, "y"); atlasFrame.W = F(dictionary2, "width"); atlasFrame.H = F(dictionary2, "height"); atlasFrame.Uv = new Rect(num / (float)((Texture)val).width, 1f - (num2 + atlasFrame.H) / (float)((Texture)val).height, atlasFrame.W / (float)((Texture)val).width, atlasFrame.H / (float)((Texture)val).height); atlasFrame.OffX = 0f - F(dictionary2, "frameX"); atlasFrame.OffY = 0f - F(dictionary2, "frameY"); atlasFrame.FrameW = (dictionary2.ContainsKey("frameWidth") ? F(dictionary2, "frameWidth") : atlasFrame.W); atlasFrame.FrameH = (dictionary2.ContainsKey("frameHeight") ? F(dictionary2, "frameHeight") : atlasFrame.H); int i; for (i = 0; i < value.Length && char.IsDigit(value[value.Length - 1 - i]); i++) { } string key = Spaces.Replace(value.Substring(0, value.Length - i), " ").Trim(); int result = 0; if (i > 0) { int.TryParse(value.Substring(value.Length - i), out result); } if (!dictionary.TryGetValue(key, out var value2)) { value2 = (dictionary[key] = new SortedList<int, AtlasFrame>()); } value2[result] = atlasFrame; } } foreach (KeyValuePair<string, SortedList<int, AtlasFrame>> item3 in dictionary) { atlas.anims[item3.Key] = new List<AtlasFrame>(item3.Value.Values); } return atlas; } private static float F(Dictionary<string, string> a, string key) { if (a.TryGetValue(key, out var value) && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } return 0f; } public List<AtlasFrame> Anim(string prefix) { if (!anims.TryGetValue(prefix, out var value)) { return null; } return value; } public AtlasFrame Frame(string prefix, int index) { List<AtlasFrame> list = Anim(prefix); if (list == null || list.Count == 0) { return null; } return list[Mathf.Clamp(index, 0, list.Count - 1)]; } } internal static class FnfAssets { internal static Atlas Notes; internal static Atlas Strums; internal static Atlas Splashes; internal static Texture2D Holds; internal static Texture2D HealthBar; internal static Texture2D Combo; internal static Texture2D[] Ratings = (Texture2D[])(object)new Texture2D[4]; internal static Texture2D[] Digits = (Texture2D[])(object)new Texture2D[10]; internal static Texture2D[] Countdown = (Texture2D[])(object)new Texture2D[3]; internal static AudioClip[] CountdownSounds = (AudioClip[])(object)new AudioClip[4]; internal static AudioClip[] MissSounds = (AudioClip[])(object)new AudioClip[3]; internal static AudioClip LossSound; internal static Texture2D Vignette; internal static Texture2D Ring; internal static Font Font; private static string loadedFrom; private static bool soundsLoaded; private static bool fontSearched; internal static void EnsureTextures() { string funkinFolder = SongLibrary.FunkinFolder; if (!(loadedFrom == funkinFolder)) { loadedFrom = funkinFolder; string path = Path.Combine(Path.Combine(funkinFolder, "assets"), "shared"); string path2 = Path.Combine(path, "images"); Notes = Atlas.Load(Path.Combine(path2, "notes.png"), Path.Combine(path2, "notes.xml")); Strums = Atlas.Load(Path.Combine(path2, "noteStrumline.png"), Path.Combine(path2, "noteStrumline.xml")); Splashes = Atlas.Load(Path.Combine(path2, "noteSplashes.png"), Path.Combine(path2, "noteSplashes.xml")); Holds = LoadTexture(Path.Combine(path2, "NOTE_hold_assets.png")); HealthBar = LoadTexture(Path.Combine(path2, "healthBar.png")); string path3 = Path.Combine(funkinFolder, Path.Combine("assets", Path.Combine("images", Path.Combine("ui", Path.Combine("popup", "funkin"))))); string[] array = new string[4] { "sick", "good", "bad", "shit" }; for (int i = 0; i < 4; i++) { Ratings[i] = LoadTexture(Path.Combine(path3, array[i] + ".png")); } for (int j = 0; j < 10; j++) { Digits[j] = LoadTexture(Path.Combine(path3, "num" + j + ".png")); } Combo = LoadTexture(Path.Combine(path3, "combo.png")); string path4 = Path.Combine(path2, Path.Combine("ui", Path.Combine("countdown", "funkin"))); string[] array2 = new string[3] { "ready", "set", "go" }; for (int k = 0; k < 3; k++) { Countdown[k] = LoadTexture(Path.Combine(path4, array2[k] + ".png")); } if ((Object)(object)Vignette == (Object)null) { Vignette = MakeRadial(128, ring: false); } if ((Object)(object)Ring == (Object)null) { Ring = MakeRadial(128, ring: true); } if ((Object)(object)Font == (Object)null) { Font = FindFont(); } RapBattlePlugin.Log.LogInfo((object)("FNF art: notes " + (Notes != null) + ", strums " + (Strums != null) + ", splashes " + (Splashes != null) + ", holds " + ((Object)(object)Holds != (Object)null) + ", font " + (((Object)(object)Font != (Object)null) ? ((Object)Font).name : "default"))); } } internal static IEnumerator EnsureSounds() { if (soundsLoaded) { yield break; } soundsLoaded = true; string sounds = Path.Combine(Path.Combine(Path.Combine(SongLibrary.FunkinFolder, "assets"), "shared"), "sounds"); string countdown = Path.Combine(sounds, Path.Combine("gameplay", Path.Combine("countdown", "funkin"))); string[] cd = new string[4] { "introTHREE", "introTWO", "introONE", "introGO" }; for (int i = 0; i < 4; i++) { int slot = i; yield return LoadClip(Path.Combine(countdown, cd[i] + ".ogg"), compressed: false, delegate(AudioClip c) { CountdownSounds[slot] = c; }); } for (int i2 = 0; i2 < 3; i2++) { int slot2 = i2; yield return LoadClip(Path.Combine(sounds, "missnote" + (i2 + 1) + ".ogg"), compressed: false, delegate(AudioClip c) { MissSounds[slot2] = c; }); } yield return LoadClip(Path.Combine(sounds, Path.Combine("gameplay", Path.Combine("gameover", "fnf_loss_sfx.ogg"))), compressed: false, delegate(AudioClip c) { LossSound = c; }); } internal static Texture2D LoadTexture(string path) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown try { if (!File.Exists(path)) { return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path), false)) { return null; } ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)32; return val; } catch (Exception ex) { RapBattlePlugin.Log.LogWarning((object)("Could not load " + path + ": " + ex.Message)); return null; } } internal static IEnumerator LoadClip(string path, bool compressed, Action<AudioClip> done) { if (string.IsNullOrEmpty(path) || !File.Exists(path)) { done(null); yield break; } UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(FileUrl(path), (AudioType)14); DownloadHandler downloadHandler = req.downloadHandler; DownloadHandlerAudioClip handler = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null); if (handler != null) { handler.compressed = compressed; } yield return req.SendWebRequest(); AudioClip clip = null; if ((int)req.result == 1) { try { clip = DownloadHandlerAudioClip.GetContent(req); } catch (Exception ex) { RapBattlePlugin.Log.LogWarning((object)("Could not decode " + path + ": " + ex.Message)); } } else { RapBattlePlugin.Log.LogWarning((object)("Could not load " + path + ": " + req.error)); } req.Dispose(); if ((Object)(object)clip != (Object)null) { ((Object)clip).name = Path.GetFileNameWithoutExtension(path); } done(clip); } private static string FileUrl(string path) { string text = Path.GetFullPath(path).Replace('\\', '/'); string[] array = text.Split('/'); StringBuilder stringBuilder = new StringBuilder("file:///"); for (int i = 0; i < array.Length; i++) { if (i > 0) { stringBuilder.Append('/'); } stringBuilder.Append((i == 0 && array[i].EndsWith(":")) ? array[i] : Uri.EscapeDataString(array[i])); } return stringBuilder.ToString(); } private static Texture2D MakeRadial(int size, bool ring) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).hideFlags = (HideFlags)32; Color[] array = (Color[])(object)new Color[size * size]; float num = (float)(size - 1) * 0.5f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num) * ((float)i - num)) / num; float num3 = ((!ring) ? Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.45f, 1.15f, num2)) : Mathf.Clamp01(1f - Mathf.Abs(num2 - 0.86f) / 0.1f)); ref Color reference = ref array[i * size + j]; reference = new Color(1f, 1f, 1f, num3); } } val.SetPixels(array); val.Apply(); return val; } internal static Font GetFont() { if ((Object)(object)Font == (Object)null && !fontSearched) { fontSearched = true; Font = FindFont(); } return Font; } private static Font FindFont() { Font val = null; Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val2 in array) { string text = ((Object)val2).name.ToLowerInvariant(); if (text.Contains("vcr")) { return val2; } if ((Object)(object)val == (Object)null && (text.Contains("mono") || text.Contains("pixel"))) { val = val2; } } return val; } } internal static class FnfLocator { private const int MaxFoldersVisited = 6000; internal static bool IsFnfFolder(string path) { if (string.IsNullOrEmpty(path)) { return false; } try { string text = Path.Combine(path, "assets"); if (!Directory.Exists(text)) { return false; } return File.Exists(Path.Combine(path, "Funkin.exe")) || Directory.Exists(Path.Combine(Path.Combine(text, "data"), "songs")); } catch (Exception) { return false; } } internal static string Resolve(string configured) { string text = (configured ?? "").Trim().Trim('"'); if (text.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { text = Path.GetDirectoryName(text); } if (IsFnfFolder(text)) { return text; } List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>(); string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); Add(list, Path.Combine(folderPath, "Downloads"), 3); Add(list, Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), 3); Add(list, Environment.GetFolderPath(Environment.SpecialFolder.Personal), 3); Add(list, Path.Combine(Path.Combine(folderPath, "OneDrive"), "Desktop"), 3); Add(list, Path.Combine(Path.Combine(folderPath, "OneDrive"), "Documents"), 3); Add(list, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "itch\\apps"), 2); Add(list, Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), 2); Add(list, Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), 2); Add(list, "C:\\Program Files (x86)\\Steam\\steamapps\\common", 2); foreach (DriveInfo item in SafeDrives()) { Add(list, Path.Combine(item.RootDirectory.FullName, "Games"), 2); Add(list, Path.Combine(item.RootDirectory.FullName, "SteamLibrary\\steamapps\\common"), 2); } Add(list, folderPath, 1); int visited = 0; foreach (KeyValuePair<string, int> item2 in list) { string text2 = Search(item2.Key, item2.Value, ref visited); if (text2 != null) { RapBattlePlugin.Log.LogInfo((object)("Found Friday Night Funkin' at " + text2)); return text2; } if (visited > 6000) { break; } } return null; } private static void Add(List<KeyValuePair<string, int>> roots, string path, int depth) { if (!string.IsNullOrEmpty(path)) { roots.Add(new KeyValuePair<string, int>(path, depth)); } } private static IEnumerable<DriveInfo> SafeDrives() { DriveInfo[] drives; try { drives = DriveInfo.GetDrives(); } catch (Exception) { yield break; } try { DriveInfo[] array = drives; foreach (DriveInfo d in array) { bool ok; try { ok = d.DriveType == DriveType.Fixed && d.IsReady; } catch (Exception) { ok = false; } if (ok) { yield return d; } } } finally { } } private static string Search(string dir, int depth, ref int visited) { if (visited > 6000) { return null; } visited++; try { if (!Directory.Exists(dir)) { return null; } if (File.Exists(Path.Combine(dir, "Funkin.exe")) && IsFnfFolder(dir)) { return dir; } if (depth <= 0) { return null; } string[] directories = Directory.GetDirectories(dir); foreach (string text in directories) { string fileName = Path.GetFileName(text); if (!fileName.StartsWith(".") && !fileName.StartsWith("$") && !(fileName == "node_modules") && !(fileName == "Windows")) { string text2 = Search(text, depth - 1, ref visited); if (text2 != null) { return text2; } } } } catch (Exception) { } return null; } } internal class BattleHud { private class Splash { public int Lane; public float T0; public int Variant; } private class Popup { public Texture2D Tex; public string Text; public Color Color; public float X; public float Y; public float Vy; public float T0; public float Life; public float Scale; public int Size; public bool Rating; } private const float NoteScale = 0.7f; private static readonly string[] Dirs = new string[4] { "Left", "Down", "Up", "Right" }; private static readonly string[] SplashColors = new string[4] { "purple", "blue", "green", "red" }; private static readonly Color[] NoteColors = (Color[])(object)new Color[4] { new Color(0.76f, 0.29f, 0.6f), new Color(0f, 1f, 1f), new Color(0.07f, 0.98f, 0.02f), new Color(0.98f, 0.22f, 0.25f) }; internal static readonly Color EnemyColor = new Color(0.9f, 0.16f, 0.2f); internal static readonly Color V1Color = new Color(0.2f, 0.6f, 1f); private readonly RapBattle b; private GUIStyle style; private readonly int[] strumAnim = new int[8]; private readonly float[] strumT0 = new float[8]; private readonly float[] confirmUntil = new float[8]; private readonly bool[] held = new bool[4]; private readonly List<Splash> splashes = new List<Splash>(); private readonly List<Popup> popups = new List<Popup>(); public float HudBop; private float iconBop; private Color flashColor; private float flashAlpha; private float flashFade = 3f; public readonly FloatTween Dark = new FloatTween(0f); public Color DarkColor = Color.black; public readonly FloatTween HudAlpha = new FloatTween(1f); public readonly FloatTween Swap = new FloatTween(0f); public readonly FloatTween Flip = new FloatTween(0f); public float Vignette; public float SwayAmount; public float SwaySpeed = 0.5f; private float glitchUntil; private float glitchIntensity; private string lyrics; private Color lyricsColor; private float lyricsUntil; private bool lyricsGlitch; private string banner; private Color bannerColor; private float bannerT0; private float bannerUntil; public Color[] PulseColors; public float[] PulseIntensities; public bool PulseOn; private int pulseIndex; private float pulseAlpha; private Color pulseColor; private int countdownImage = -1; private float countdownT0; private string infoTitle; private string infoSub; private float infoT0 = -100f; private int result; private float resultT0; private int drawStart; public bool Boss; private float bossPulse; private float Now => b.SongPos; public BattleHud(RapBattle battle) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) b = battle; } public void Press(int lane) { if (strumAnim[lane + 4] == 0) { strumAnim[lane + 4] = 1; strumT0[lane + 4] = Time.unscaledTime; } } public void SetHeld(int lane, bool down) { held[lane] = down; } public void PlayerHit(NoteData n, int rating) { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) int num = n.Lane + 4; strumAnim[num] = 2; strumT0[num] = Time.unscaledTime; confirmUntil[num] = Time.unscaledTime + 0.12f; if (rating == 0) { splashes.Add(new Splash { Lane = n.Lane, T0 = Time.unscaledTime, Variant = Random.Range(1, 3) }); } if (!RatingSpot(out var at, out var scale)) { return; } for (int num2 = popups.Count - 1; num2 >= 0; num2--) { if (popups[num2].Rating) { popups.RemoveAt(num2); } } Texture2D tex = ((rating >= 0 && rating < 4) ? FnfAssets.Ratings[rating] : null); string[] array = new string[4] { "SICK!!", "GOOD!", "BAD", "SHIT" }; Color[] array2 = (Color[])(object)new Color[4] { new Color(0.4f, 0.9f, 1f), new Color(0.4f, 1f, 0.5f), new Color(1f, 0.7f, 0.3f), new Color(0.7f, 0.5f, 0.4f) }; popups.Add(new Popup { Tex = tex, Text = array[rating], Color = array2[rating], X = at.x, Y = at.y, Vy = -90f * scale, T0 = Time.unscaledTime, Life = 0.32f, Scale = 0.62f * scale, Size = (int)(40f * scale), Rating = true }); AddComboNumbers(at, scale); } private bool RatingSpot(out Vector2 at, out float scale) { //IL_0016: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) string value = RapBattlePlugin.RatingsPosition.Value; at = new Vector2(560f, 300f); scale = 0.75f; if (value == "Off") { return false; } if (value == "Center") { return true; } float num = DownAmount(); float num2 = Mathf.Lerp(100f, 620f, num); float num3 = num2 + Mathf.Lerp(75f, -75f, num); float num4 = (RapBattlePlugin.Middlescroll.Value ? 300f : 640f); at = new Vector2(num4, num3); scale = 0.5f; return true; } private void AddComboNumbers(Vector2 at, float scale) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) int combo = b.Combo; if (combo >= 1) { string text = combo.ToString("000"); float num = 40f * scale / 0.75f; float num2 = at.x - num * (float)(text.Length - 1) * 0.5f; for (int i = 0; i < text.Length; i++) { int num3 = text[i] - 48; popups.Add(new Popup { Tex = FnfAssets.Digits[num3], Text = text[i].ToString(), Color = Color.white, X = num2 + (float)i * num, Y = at.y + 60f * scale / 0.75f, Vy = -70f * scale, T0 = Time.unscaledTime, Life = 0.3f, Scale = 0.45f * scale / 0.75f, Size = (int)(34f * scale), Rating = true }); } } } public void EnemyHit(NoteData n) { int lane = n.Lane; strumAnim[lane] = ((n.Length > 0f) ? 3 : 2); strumT0[lane] = Time.unscaledTime; confirmUntil[lane] = n.Time + Mathf.Max(n.Length, 150f); } public void Miss() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!RatingSpot(out var at, out var scale)) { return; } for (int num = popups.Count - 1; num >= 0; num--) { if (popups[num].Rating) { popups.RemoveAt(num); } } popups.Add(new Popup { Text = "MISS", Color = new Color(0.75f, 0.4f, 1f), X = at.x, Y = at.y, Vy = -60f * scale, T0 = Time.unscaledTime, Life = 0.35f, Scale = 1f, Size = (int)(34f * scale), Rating = true }); } public void Message(string text, Color color, float x, float y, int size) { //IL_0014: 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) popups.Add(new Popup { Text = text, Color = color, X = x, Y = y, Vy = -60f, T0 = Time.unscaledTime, Life = 0.9f, Scale = 1f, Size = size }); } public void Flash(Color color, float seconds, float strength) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(strength) * (RapBattlePlugin.ScreenFlashes.Value ? 1f : 0.15f); if (!(num < flashAlpha) || !(flashAlpha > 0.05f)) { flashColor = color; flashAlpha = num; flashFade = num / Mathf.Max(0.05f, seconds); } } public void Glitch(float seconds, float intensity) { glitchUntil = Time.unscaledTime + seconds; glitchIntensity = Mathf.Clamp01(intensity); } public void Lyrics(string text, Color color, float seconds, bool glitch) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) lyrics = text; lyricsColor = color; lyricsUntil = Time.unscaledTime + seconds; lyricsGlitch = glitch; } public void Banner(string text, Color color, float seconds) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) banner = text; bannerColor = color; bannerT0 = Time.unscaledTime; bannerUntil = Time.unscaledTime + seconds; } public void Countdown(int image) { countdownImage = image; countdownT0 = Time.unscaledTime; } public void SongInfo(string title, string sub) { infoTitle = title; infoSub = sub; infoT0 = Time.unscaledTime; } public void Result(bool won) { result = (won ? 1 : 2); resultT0 = Time.unscaledTime; } public void Beat(int beat) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) iconBop = 1f; if (Boss) { bossPulse = 1f; } if (PulseOn && PulseColors != null && PulseColors.Length > 0) { pulseIndex = (pulseIndex + 1) % PulseColors.Length; pulseColor = PulseColors[pulseIndex]; float num = ((PulseIntensities != null && PulseIntensities.Length > 0) ? PulseIntensities[pulseIndex % PulseIntensities.Length] : 0.6f); pulseAlpha = 0.28f * num * (RapBattlePlugin.ScreenFlashes.Value ? 1f : 0.3f); } } public void Tick(float dt) { HudBop *= Mathf.Exp(-3.1f * dt); iconBop = Mathf.MoveTowards(iconBop, 0f, dt * 6f); bossPulse = Mathf.MoveTowards(bossPulse, 0f, dt * 3f); flashAlpha = Mathf.MoveTowards(flashAlpha, 0f, flashFade * dt); pulseAlpha = Mathf.MoveTowards(pulseAlpha, 0f, dt * 0.9f); for (int i = 0; i < 4; i++) { int num = i + 4; if (strumAnim[num] != 0 && !held[i] && Time.unscaledTime >= confirmUntil[num]) { strumAnim[num] = 0; } if (strumAnim[num] == 2 && b.IsHolding(i) && Time.unscaledTime - strumT0[num] > 1f / 6f) { strumAnim[num] = 3; strumT0[num] = Time.unscaledTime; } if (strumAnim[i] != 0 && Now > confirmUntil[i]) { strumAnim[i] = 0; } } for (int num2 = splashes.Count - 1; num2 >= 0; num2--) { if (Time.unscaledTime - splashes[num2].T0 > 0.3f) { splashes.RemoveAt(num2); } } for (int num3 = popups.Count - 1; num3 >= 0; num3--) { Popup popup = popups[num3]; if (Time.unscaledTime - popup.T0 > popup.Life + 0.25f) { popups.RemoveAt(num3); } else { popup.Vy += (popup.Rating ? 240f : 550f) * dt; popup.Y += popup.Vy * dt; } } } private void InitStyle() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown style = new GUIStyle(GUI.skin.label); style.richText = false; style.wordWrap = false; style.clipping = (TextClipping)0; if ((Object)(object)FnfAssets.Font != (Object)null) { style.font = FnfAssets.Font; } } public void Draw() { //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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) if (style == null) { InitStyle(); } float num = (float)Screen.height / 720f; float num2 = (float)Screen.width / num; float num3 = (num2 - 1280f) * 0.5f; Matrix4x4 val = (GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f)) * Matrix4x4.Translate(new Vector3(num3, 0f, 0f))); DrawOverlays(new Rect(0f - num3 - 2f, -2f, num2 + 4f, 724f)); Vector2 val3 = Vector2.zero; if (Time.unscaledTime < glitchUntil) { val3 = new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f)) * 14f * glitchIntensity; } float num4 = 1f + HudBop; GUI.matrix = val * Matrix4x4.Translate(new Vector3(640f + val3.x, 360f + val3.y, 0f)) * Matrix4x4.Scale(new Vector3(num4, num4, 1f)) * Matrix4x4.Translate(new Vector3(-640f, -360f, 0f)); float num5 = Mathf.Clamp01(HudAlpha.Value(Now)); if (b.Chart != null && num5 > 0.01f) { DrawStrumline(player: false, num5); DrawStrumline(player: true, num5); DrawHealth(num5); } DrawPopups(); DrawCountdown(); DrawAttack(); DrawLyrics(); DrawBanner(); DrawInfo(); DrawResult(); DrawLoading(); GUI.matrix = Matrix4x4.identity; GUI.color = Color.white; } private void DrawOverlays(Rect full) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp01(Dark.Value(Now)); if (num > 0.005f) { Fill(full, new Color(DarkColor.r, DarkColor.g, DarkColor.b, num)); } if (pulseAlpha > 0.005f) { Fill(full, new Color(pulseColor.r, pulseColor.g, pulseColor.b, pulseAlpha)); } if (Vignette > 0.01f && (Object)(object)FnfAssets.Vignette != (Object)null) { GUI.color = new Color(0f, 0f, 0f, Mathf.Clamp01(Vignette)); GUI.DrawTexture(full, (Texture)(object)FnfAssets.Vignette, (ScaleMode)0, true); } if (Boss && (Object)(object)FnfAssets.Vignette != (Object)null) { float num2 = (RapBattlePlugin.ScreenFlashes.Value ? 1f : 0.4f); GUI.color = new Color(0.85f, 0f, 0.05f, (0.3f + 0.35f * bossPulse) * num2); GUI.DrawTexture(full, (Texture)(object)FnfAssets.Vignette, (ScaleMode)0, true); } if (Time.unscaledTime < glitchUntil && RapBattlePlugin.ScreenFlashes.Value) { int num3 = 2 + (int)(glitchIntensity * 6f); for (int i = 0; i < num3; i++) { float num4 = Random.Range(0f, 720f); Color c = ((Random.value > 0.5f) ? new Color(1f, 0f, 0.4f, 0.25f) : new Color(0f, 1f, 1f, 0.25f)); Fill(new Rect(((Rect)(ref full)).x, num4, ((Rect)(ref full)).width, Random.Range(2f, 18f) * (0.5f + glitchIntensity)), c); } } if (flashAlpha > 0.005f) { Fill(full, new Color(flashColor.r, flashColor.g, flashColor.b, flashAlpha)); } } private float StrumX(bool player, int lane) { float num = 112f + (float)lane * 112f; float num2 = (RapBattlePlugin.Middlescroll.Value ? (472f + (float)lane * 112f) : (832f + (float)lane * 112f)); float num3 = Mathf.Clamp01(Swap.Value(Now)); float num4 = (player ? Mathf.Lerp(num2, num, num3) : Mathf.Lerp(num, num2, num3)); if (SwayAmount > 0.001f) { num4 += Mathf.Sin(Now / 1000f * (float)Math.PI * 2f * SwaySpeed + (float)lane * 0.8f + (player ? 0f : 2f)) * SwayAmount * 70f; } return num4; } private float DownAmount() { float num = Mathf.Clamp01(Flip.Value(Now)); if (!RapBattlePlugin.Downscroll.Value) { return num; } return 1f - num; } private void DrawStrumline(bool player, float alpha) { //IL_038a: Unknown result type (might be due to invalid IL or missing references) if (!player && RapBattlePlugin.Middlescroll.Value) { return; } float num = DownAmount(); float num2 = Mathf.Lerp(100f, 620f, num); float num3 = Mathf.Lerp(1f, -1f, num); float num4 = 0.45f * b.ScrollSpeed; for (int i = 0; i < 4; i++) { DrawStrum(player, i, StrumX(player, i), num2, alpha); } List<NoteData> notes = b.Chart.Notes; float now = Now; float num5 = 900f / Mathf.Max(0.1f, num4); while (drawStart < notes.Count && notes[drawStart].Time + notes[drawStart].Length < now - 2000f) { drawStart++; } for (int j = drawStart; j < notes.Count; j++) { NoteData noteData = notes[j]; if (noteData.Time > now + num5) { break; } if (noteData.Player != player || noteData.Length <= 0f || noteData.HoldDone) { continue; } float num6 = noteData.Time + noteData.Length; if (!(num6 < now - 200f)) { float x = StrumX(player, noteData.Lane); bool flag = noteData.Hit && (noteData.Holding || (!player && now < num6)); if (!noteData.Hit || flag || noteData.Dropped) { float headY = (flag ? num2 : (num2 + num3 * (noteData.Time - now) * num4)); float tailY = num2 + num3 * (num6 - now) * num4; float alpha2 = alpha * ((noteData.Dropped || noteData.Missed) ? 0.3f : 0.75f); DrawHold(noteData.Lane, x, headY, tailY, num3, alpha2); } } } for (int k = drawStart; k < notes.Count; k++) { NoteData noteData2 = notes[k]; if (noteData2.Time > now + num5) { break; } if (noteData2.Player == player && !noteData2.Hit) { float num7 = num2 + num3 * (noteData2.Time - now) * num4; if (!(num7 < -120f) && !(num7 > 840f)) { float alpha3 = alpha * (noteData2.Missed ? 0.35f : 1f); DrawNote(noteData2, StrumX(player, noteData2.Lane), num7, alpha3); } } } if (!player) { return; } foreach (Splash splash in splashes) { int index = (int)((Time.unscaledTime - splash.T0) * 24f); AtlasFrame atlasFrame = ((FnfAssets.Splashes != null) ? FnfAssets.Splashes.Frame("note impact " + splash.Variant + " " + SplashColors[splash.Lane], index) : null); if (atlasFrame != null) { DrawFrame(FnfAssets.Splashes.Texture, atlasFrame, StrumX(player: true, splash.Lane), num2, 0.8f, new Color(1f, 1f, 1f, 0.75f * alpha), flipY: false); } } } private void DrawStrum(bool player, int lane, float x, float y, float alpha) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) int num = (player ? (lane + 4) : lane); Atlas strums = FnfAssets.Strums; if (strums == null) { Fill(Centered(x, y, 100f, 100f), new Color(0.6f, 0.6f, 0.65f, 0.6f * alpha)); return; } int num2 = (int)((Time.unscaledTime - strumT0[num]) * 24f); AtlasFrame atlasFrame = strumAnim[num] switch { 1 => strums.Frame("press" + Dirs[lane], Mathf.Min(num2, 3)), 2 => strums.Frame("confirm" + Dirs[lane], Mathf.Min(num2, 3)), 3 => strums.Frame("confirmHold" + Dirs[lane], num2 % 4), _ => strums.Frame("static" + Dirs[lane], 0), }; if (atlasFrame != null) { DrawFrame(strums.Texture, atlasFrame, x, y, 0.7f, new Color(1f, 1f, 1f, alpha), flipY: false); } } private void DrawNote(NoteData n, float x, float y, float alpha) { //IL_0129: 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_0111: 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_00ab: 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_00c2: 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) AtlasFrame atlasFrame = ((FnfAssets.Notes != null) ? FnfAssets.Notes.Frame("note" + Dirs[n.Lane], 0) : null); if (n.Avoid) { float num = 0.75f + 0.25f * Mathf.Sin(Time.unscaledTime * 12f); if (atlasFrame != null) { DrawFrame(FnfAssets.Notes.Texture, atlasFrame, x, y, 0.7f, new Color(0.32f * num, 0.04f, 0.08f, alpha), flipY: false); } else { Fill(Centered(x, y, 96f, 96f), new Color(0.3f, 0f, 0f, alpha)); } Text(Centered(x, y, 100f, 100f), "X", 64, new Color(1f, 0.15f, 0.15f, alpha), (TextAnchor)4); } else if (atlasFrame != null) { DrawFrame(FnfAssets.Notes.Texture, atlasFrame, x, y, 0.7f, new Color(1f, 1f, 1f, alpha), flipY: false); } else { Fill(Centered(x, y, 96f, 96f), new Color(NoteColors[n.Lane].r, NoteColors[n.Lane].g, NoteColors[n.Lane].b, alpha)); } } private void DrawHold(int lane, float x, float headY, float tailY, float sign, float alpha) { //IL_013d: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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) float num = (tailY - headY) * sign; if (num <= 1f) { return; } float num2 = 36.399998f; Texture2D holds = FnfAssets.Holds; if ((Object)(object)holds == (Object)null) { Color val = NoteColors[lane]; Fill((sign > 0f) ? new Rect(x - num2 * 0.35f, headY, num2 * 0.7f, num) : new Rect(x - num2 * 0.35f, headY - num, num2 * 0.7f, num), new Color(val.r, val.g, val.b, alpha)); return; } float num3 = 52f / (float)((Texture)holds).width; float num4 = 64f; float num5 = num4 * 0.7f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(num3 * (float)(lane * 2), 2f / (float)((Texture)holds).height, num3, ((float)((Texture)holds).height - 4f) / (float)((Texture)holds).height); float num6 = Mathf.Min(num5, num); float num7 = num - num6; float num8 = num6 / num5; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(num3 * (float)(lane * 2 + 1), 1f - num4 / (float)((Texture)holds).height, num3, num4 / (float)((Texture)holds).height * num8); GUI.color = new Color(1f, 1f, 1f, alpha); if (sign > 0f) { if (num7 > 0f) { GUI.DrawTextureWithTexCoords(new Rect(x - num2 * 0.5f, headY, num2, num7), (Texture)(object)holds, val2); } GUI.DrawTextureWithTexCoords(new Rect(x - num2 * 0.5f, headY + num7, num2, num6), (Texture)(object)holds, val3); return; } if (num7 > 0f) { GUI.DrawTextureWithTexCoords(new Rect(x - num2 * 0.5f, headY - num7, num2, num7), (Texture)(object)holds, val2); } Rect val4 = default(Rect); ((Rect)(ref val4))..ctor(((Rect)(ref val3)).x, ((Rect)(ref val3)).y + ((Rect)(ref val3)).height, ((Rect)(ref val3)).width, 0f - ((Rect)(ref val3)).height); GUI.DrawTextureWithTexCoords(new Rect(x - num2 * 0.5f, headY - num, num2, num6), (Texture)(object)holds, val4); } private void DrawHealth(float alpha) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_0138: 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_0167: 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_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) float num = DownAmount(); float num2 = ((num > 0.5f) ? 79.2f : 640.8f); float num3 = (((Object)(object)FnfAssets.HealthBar != (Object)null) ? ((float)((Texture)FnfAssets.HealthBar).width) : 601f); float num4 = (((Object)(object)FnfAssets.HealthBar != (Object)null) ? ((float)((Texture)FnfAssets.HealthBar).height) : 19f); Rect val = default(Rect); ((Rect)(ref val))..ctor(640f - num3 * 0.5f, num2 - num4 * 0.5f, num3, num4); Fill(new Rect(((Rect)(ref val)).x - 4f, ((Rect)(ref val)).y - 4f, ((Rect)(ref val)).width + 8f, ((Rect)(ref val)).height + 8f), new Color(0f, 0f, 0f, alpha)); float num5 = Mathf.Clamp01(b.Health / 2f); float num6 = ((Rect)(ref val)).x + ((Rect)(ref val)).width * (1f - num5); Fill(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, num6 - ((Rect)(ref val)).x, ((Rect)(ref val)).height), new Color(EnemyColor.r, EnemyColor.g, EnemyColor.b, alpha)); Fill(new Rect(num6, ((Rect)(ref val)).y, ((Rect)(ref val)).xMax - num6, ((Rect)(ref val)).height), new Color(V1Color.r, V1Color.g, V1Color.b, alpha)); float num7 = 1f + 0.2f * iconBop * iconBop; int size = (int)(26f * num7); bool flag = num5 < 0.2f; bool flag2 = num5 > 0.8f; Text(new Rect(num6 - 330f, num2 - 30f, 316f, 60f), b.EnemyName, size, new Color(1f, flag2 ? 0.55f : 1f, flag2 ? 0.55f : 1f, alpha), (TextAnchor)5); Text(new Rect(num6 + 14f, num2 - 30f, 200f, 60f), "V1", size, new Color(1f, flag ? 0.55f : 1f, flag ? 0.55f : 1f, alpha), (TextAnchor)3); string text = ((b.Misses != 0) ? "" : ((b.Judged[1] + b.Judged[2] + b.Judged[3] == 0) ? " [SFC]" : " [FC]")); string s = "Score: " + b.Score.ToString("N0") + " Misses: " + b.Misses + " Accuracy: " + (b.Accuracy * 100f).ToString("0.00") + "%" + ((b.Accuracy