Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ReincarnationDisplay v1.0.1
plugins/ReincarnationDisplay/ReincarnationDisplay.dll
Decompiled 4 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG; using Microsoft.CodeAnalysis; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.EntityLogic; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("RoR2")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ReincarnationDisplay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+6f3ba661d519d343e5ffd10432c3ac7892369056")] [assembly: AssemblyProduct("ReincarnationDisplay")] [assembly: AssemblyTitle("ReincarnationDisplay")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ReincarnationDisplay { internal sealed class PluginConfig { public readonly ConfigEntry<bool> ShowPanel; public readonly ConfigEntry<bool> ShowZoneIndicator; public readonly ConfigEntry<float> PanelOffsetY; public readonly ConfigEntry<float> PanelScale; public readonly ConfigEntry<bool> ShowWorldRings; public readonly ConfigEntry<float> RingMaxDistance; public readonly ConfigEntry<float> StageStartWindowSeconds; public readonly ConfigEntry<bool> HideStageStartZoneAfterWindow; public readonly ConfigEntry<bool> DebugLogging; public readonly ConfigEntry<bool> DebugAlwaysShow; public readonly ConfigEntry<KeyboardShortcut> DumpZonesKey; public PluginConfig(ConfigFile config) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) ShowPanel = config.Bind<bool>("Panel", "ShowPanel", true, "Show the panel above the N'tormat icon while standing in a valid sacrifice zone."); ShowZoneIndicator = config.Bind<bool>("Panel", "ShowZoneIndicator", true, "When not standing in a zone, show a one-line hint above the N'tormat icon if the stage has a sacrifice zone. The stage-start reroll zone doesn't count."); PanelOffsetY = config.Bind<float>("Panel", "PanelOffsetY", -6f, "Vertical gap, in UI pixels, between the panel and whatever sits above the N'tormat icon (such as the page selector)."); PanelScale = config.Bind<float>("Panel", "PanelScale", 1f, "Scale multiplier for the panel."); ShowWorldRings = config.Bind<bool>("World", "ShowWorldRings", true, "Draw rings on the ground marking the edge of each valid sacrifice zone."); RingMaxDistance = config.Bind<float>("World", "RingMaxDistance", 300f, "Rings further than this many meters away are hidden."); StageStartWindowSeconds = config.Bind<float>("Timing", "StageStartWindowSeconds", 30f, "Fallback length of the stage-start reroll window, used only if the zone has no timer of its own."); HideStageStartZoneAfterWindow = config.Bind<bool>("Timing", "HideStageStartZoneAfterWindow", true, "Stop treating the stage-start zone as valid once the window has elapsed."); DebugLogging = config.Bind<bool>("Debug", "DebugLogging", false, "Log every sacrifice zone as it appears, and enable the zone dump key."); DebugAlwaysShow = config.Bind<bool>("Debug", "DebugAlwaysShow", false, "Show the panel and zone rings even without a Reincarnation page, for testing."); DumpZonesKey = config.Bind<KeyboardShortcut>("Debug", "DumpZonesKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "With DebugLogging on, press to log every sacrifice zone in the current stage."); } } internal sealed class ReincarnationDisplayController : MonoBehaviour { private const float BuffMismatchGrace = 0.5f; private readonly List<ZoneInfo> zones = new List<ZoneInfo>(); private HUD hud; private ZoneHudPanel panel; private ZoneWorldRings rings; private GameObject cachedBodyObject; private CharacterBody cachedBody; private float buffMismatchTime; private bool reportedBuffMismatch; private void Awake() { hud = ((Component)this).GetComponent<HUD>(); rings = ZoneWorldRings.Create(); } private void OnDestroy() { if (Object.op_Implicit((Object)(object)rings)) { Object.Destroy((Object)(object)((Component)rings).gameObject); } } private void Update() { //IL_0164: Unknown result type (might be due to invalid IL or missing references) PluginConfig settings = ReincarnationDisplayPlugin.Settings; CharacterBody targetBody = GetTargetBody(); zones.Clear(); int num = -1; PageState pageState = ZoneScanner.GetPageState(targetBody); PageState pageState2 = pageState; if (pageState2 == PageState.None && settings.DebugAlwaysShow.Value && Object.op_Implicit((Object)(object)targetBody)) { pageState2 = PageState.Usable; } bool num2 = pageState2 != PageState.None; if (num2) { num = ZoneScanner.Scan(targetBody, zones); } if (settings.DebugLogging.Value) { ZoneDebugDump.LogNewZones(); ReportBuffMismatch(targetBody, pageState == PageState.Usable, num >= 0); } if (!Object.op_Implicit((Object)(object)panel) && Object.op_Implicit((Object)(object)hud.keyItemIcon)) { panel = ZoneHudPanel.Create(hud.keyItemIcon); } if (Object.op_Implicit((Object)(object)panel)) { int num3 = CountIndicatorZones(); if (settings.ShowPanel.Value && num >= 0) { string disabledCause = ((pageState2 == PageState.Disabled) ? ZoneScanner.DescribeDisabledCause(targetBody) : null); panel.Show(zones[num], disabledCause); } else if (settings.ShowZoneIndicator.Value && num3 > 0) { panel.ShowIndicator(num3, pageState2 == PageState.Disabled); } else { panel.Hide(); } } if (!Object.op_Implicit((Object)(object)rings)) { rings = ZoneWorldRings.Create(); } if (num2 && settings.ShowWorldRings.Value) { rings.UpdateRings(zones, targetBody.corePosition, settings.RingMaxDistance.Value); } else { rings.Clear(); } } private int CountIndicatorZones() { int num = 0; foreach (ZoneInfo zone in zones) { if (!zone.IsStageStart) { num++; } } return num; } private CharacterBody GetTargetBody() { GameObject targetBodyObject = hud.targetBodyObject; if ((Object)(object)targetBodyObject != (Object)(object)cachedBodyObject) { cachedBodyObject = targetBodyObject; cachedBody = (Object.op_Implicit((Object)(object)targetBodyObject) ? targetBodyObject.GetComponent<CharacterBody>() : null); } return cachedBody; } private void ReportBuffMismatch(CharacterBody body, bool usable, bool inZone) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) bool flag = usable && ZoneScanner.HasReadyBuff(body); if (!usable || flag == inZone) { buffMismatchTime = 0f; reportedBuffMismatch = false; return; } buffMismatchTime += Time.deltaTime; if (buffMismatchTime >= 0.5f && !reportedBuffMismatch) { reportedBuffMismatch = true; ReincarnationDisplayPlugin.Log.LogWarning((object)$"In-zone mismatch: local check says {inZone}, server buff says {flag} at {body.corePosition}"); } } } [BepInPlugin("sevenstack.ReincarnationDisplay", "ReincarnationDisplay", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ReincarnationDisplayPlugin : BaseUnityPlugin { public const string PluginGUID = "sevenstack.ReincarnationDisplay"; public const string PluginName = "ReincarnationDisplay"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Log; internal static PluginConfig Settings; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Settings = new PluginConfig(((BaseUnityPlugin)this).Config); if (RiskOfOptionsCompat.Enabled) { RiskOfOptionsCompat.Register(Settings); } HUD.onHudTargetChangedGlobal += OnHudTargetChanged; } private void OnDestroy() { HUD.onHudTargetChangedGlobal -= OnHudTargetChanged; } private void Update() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (Settings.DebugLogging.Value) { KeyboardShortcut value = Settings.DumpZonesKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ZoneDebugDump.DumpAll(); } } } private static void OnHudTargetChanged(HUD hud) { if (Object.op_Implicit((Object)(object)hud) && !Object.op_Implicit((Object)(object)((Component)hud).GetComponent<ReincarnationDisplayController>())) { ((Component)hud).gameObject.AddComponent<ReincarnationDisplayController>(); } } } internal static class RiskOfOptionsCompat { public const string GUID = "com.rune580.riskofoptions"; private const string IconResource = "ReincarnationDisplay.icon.png"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void Register(PluginConfig settings) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_010c: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_014d: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown ModSettingsManager.SetModDescription("Shows the Reincarnation page's sacrifice zones, where a sacrifice will send you, and the stage-start window."); Sprite val = LoadIcon(); if (Object.op_Implicit((Object)(object)val)) { ModSettingsManager.SetModIcon(val); } ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.ShowPanel)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.ShowZoneIndicator)); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(settings.PanelOffsetY, new StepSliderConfig { min = -50f, max = 200f, increment = 1f, FormatString = "{0:0}px" })); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(settings.PanelScale, new StepSliderConfig { min = 0.5f, max = 2f, increment = 0.05f, FormatString = "{0:0.00}x" })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.ShowWorldRings)); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(settings.RingMaxDistance, new StepSliderConfig { min = 25f, max = 1000f, increment = 25f, FormatString = "{0:0}m" })); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(settings.StageStartWindowSeconds, new StepSliderConfig { min = 5f, max = 120f, increment = 1f, FormatString = "{0:0}s" })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.HideStageStartZoneAfterWindow)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.DebugLogging)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(settings.DebugAlwaysShow)); } private static Sprite LoadIcon() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) using Stream stream = typeof(RiskOfOptionsCompat).Assembly.GetManifestResourceStream("ReincarnationDisplay.icon.png"); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, memoryStream.ToArray())) { return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } internal static class ZoneDebugDump { private static readonly HashSet<int> loggedZoneIds = new HashSet<int>(); private static readonly List<SceneDef> candidates = new List<SceneDef>(); public static void LogNewZones() { foreach (CursedBookSacrificeZone instance in CursedBookSacrificeZone.instanceList) { if (Object.op_Implicit((Object)(object)instance) && loggedZoneIds.Add(((Object)instance).GetInstanceID())) { LogZone(instance, "New sacrifice zone"); } } } public static void DumpAll() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) float num; if (!Object.op_Implicit((Object)(object)Stage.instance)) { num = -1f; } else { FixedTimeStamp entryTime = Stage.instance.entryTime; num = ((FixedTimeStamp)(ref entryTime)).timeSince; } float num2 = num; ManualLogSource log = ReincarnationDisplayPlugin.Log; SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef; log.LogInfo((object)($"=== Sacrifice zone dump: scene={((mostRecentSceneDef != null) ? mostRecentSceneDef.cachedName : null)} stageAge={num2:0.00}s " + $"zones={CursedBookSacrificeZone.instanceList.Count} ===")); foreach (CursedBookSacrificeZone instance2 in CursedBookSacrificeZone.instanceList) { if (Object.op_Implicit((Object)(object)instance2)) { LogZone(instance2, "Sacrifice zone"); } } DLC4SacrificeZoneSpawner instance = DLC4SacrificeZoneSpawner.instance; GameObject val = ((Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.reincarnateCard)) ? instance.reincarnateCard.prefab : null); if (Object.op_Implicit((Object)(object)val)) { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("Stage-start spawn card prefab '" + ((Object)val).name + "':"); AppendComponents(stringBuilder, val); ReincarnationDisplayPlugin.Log.LogInfo((object)stringBuilder.ToString()); } else { ReincarnationDisplayPlugin.Log.LogInfo((object)"No DLC4SacrificeZoneSpawner in this scene."); } } private static void LogZone(CursedBookSacrificeZone zone, string title) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_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_02a0: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"{title} '{GetPath(((Component)zone).transform)}' active={((Component)zone).gameObject.activeInHierarchy} position={((Component)zone).transform.position}"); stringBuilder.AppendLine($" behaviour={zone.behaviour} isDisabled={zone.isDisabled} " + $"runFlag={zone.runFlagCondition}:'{zone.runFlagName}'={zone.runFlagConditionResult} pageRequirement={zone.pageRequirement}"); string[] obj = new string[7] { $" reroll={zone.useRerollSceneInstead} next={zone.useNextSceneInstead} explicit={zone.useExplicitSceneInstead} ", "explicitScene=", null, null, null, null, null }; SceneDef explicitScene = zone.explicitScene; obj[2] = ((explicitScene != null) ? explicitScene.cachedName : null); obj[3] = " sceneCollection="; SceneCollection sceneCollection = zone.sceneCollection; obj[4] = ((sceneCollection != null) ? ((Object)sceneCollection).name : null); obj[5] = " "; SceneTierCollection sceneTierCollection = zone.sceneTierCollection; obj[6] = $"sceneTierCollection={((sceneTierCollection != null) ? ((Object)sceneTierCollection).name : null)} doNotIncrementStageNumber={zone.doNotIncrementStageNumber}"; stringBuilder.AppendLine(string.Concat(obj)); stringBuilder.AppendLine(" shape=" + DescribeShape(zone.zone)); Timer component = ((Component)zone).GetComponent<Timer>(); if (Object.op_Implicit((Object)(object)component)) { float num; if (!Object.op_Implicit((Object)(object)Stage.instance)) { num = -1f; } else { FixedTimeStamp entryTime = Stage.instance.entryTime; num = ((FixedTimeStamp)(ref entryTime)).timeSince; } float num2 = num; stringBuilder.AppendLine($" timer running={component.timerRunning} stopwatch={component.stopwatch:0.00}/{component.duration} stageAge={num2:0.00}s"); } if (Object.op_Implicit((Object)(object)Run.instance)) { bool keepsStageCount; string arg = ZoneScanner.DescribeOutcome(zone, out keepsStageCount); stringBuilder.AppendLine($" outcome='{arg}' keepsStageCount={keepsStageCount}"); if (!zone.useExplicitSceneInstead && !zone.useNextSceneInstead && !zone.useRerollSceneInstead) { ZoneScanner.GetCollectionCandidates(zone, candidates); stringBuilder.Append(" candidates:"); foreach (SceneDef candidate in candidates) { stringBuilder.Append($" {candidate.cachedName} ({ZoneScanner.SceneName(candidate)}, {candidate.sceneType})"); } stringBuilder.AppendLine(); } } AppendComponents(stringBuilder, ((Component)zone).gameObject); ReincarnationDisplayPlugin.Log.LogInfo((object)stringBuilder.ToString()); } private static string DescribeShape(IZone zone) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) VerticalTubeZone val = (VerticalTubeZone)(object)((zone is VerticalTubeZone) ? zone : null); if (val == null) { SphereZone val2 = (SphereZone)(object)((zone is SphereZone) ? zone : null); if (val2 == null) { BoxZone val3 = (BoxZone)(object)((zone is BoxZone) ? zone : null); if (val3 == null) { if (zone == null) { return "none"; } return ((object)zone).GetType().FullName; } return $"BoxZone halfExtents={((Component)val3).transform.lossyScale * 0.5f} inverted={val3.isInverted} enabled={((Behaviour)val3).enabled}"; } return $"SphereZone radius={val2.radius} inverted={val2.isInverted} enabled={((Behaviour)val2).enabled}"; } return $"VerticalTubeZone radius={val.radius} enabled={((Behaviour)val).enabled}"; } private static void AppendComponents(StringBuilder builder, GameObject root) { Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val)) { continue; } Type type = ((object)val).GetType(); builder.Append(" [" + GetPath(val.transform) + "] " + type.FullName); Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if (val2 != null) { builder.Append(val2.enabled ? "" : " (disabled)"); } builder.AppendLine(); if (type.Namespace != null && type.Namespace.StartsWith("UnityEngine")) { continue; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { bool num = fieldInfo.IsPublic || fieldInfo.IsDefined(typeof(SerializeField), inherit: false); Type fieldType = fieldInfo.FieldType; if (num && (fieldType.IsPrimitive || fieldType.IsEnum || fieldType == typeof(string))) { builder.AppendLine($" {fieldInfo.Name}={fieldInfo.GetValue(val)}"); } } } } private static string GetPath(Transform transform) { string text = ((Object)transform).name; Transform parent = transform.parent; while (Object.op_Implicit((Object)(object)parent)) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } } internal sealed class ZoneHudPanel : MonoBehaviour { private enum Mode { Zone, Indicator } private const float PanelWidth = 260f; private const float FontSize = 15f; private const float FadeDuration = 0.15f; private const float ScreenEdgeMargin = 4f; private static readonly Color BackgroundColor = new Color(0.07f, 0.03f, 0.1f, 0.85f); private const string HeaderColor = "#C38BFF"; private const string DisabledHeaderColor = "#FF5A5A"; private const string NoteColor = "#A0A0A0"; private const string WindowColor = "#E6D9FF"; private const string WindowWarningColor = "#FFC24D"; private const string WindowCriticalColor = "#FF5A5A"; private RectTransform rectTransform; private RectTransform canvasRectTransform; private KeyItemIcon icon; private RectTransform iconRectTransform; private CanvasGroup canvasGroup; private ContentSizeFitter fitter; private TextMeshProUGUI label; private readonly Vector3[] corners = (Vector3[])(object)new Vector3[4]; private readonly Vector3[] canvasCorners = (Vector3[])(object)new Vector3[4]; private bool visible; private Mode mode; private bool textDirty = true; private int shownIndicatorCount; private bool shownIndicatorDisabled; private CursedBookSacrificeZone describedZone; private string outcome; private bool keepsStageCount; private int shownWindowTenths = int.MinValue; private string shownDisabledCause; public static ZoneHudPanel Create(KeyItemIcon icon) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_0133: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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_01cf: Expected O, but got Unknown //IL_01f0: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ReincarnationZonePanel", new Type[1] { typeof(RectTransform) }); val.layer = ((Component)icon).gameObject.layer; RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent(((Component)icon).transform, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 1f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0f); val2.sizeDelta = new Vector2(260f, 0f); val.AddComponent<LayoutElement>().ignoreLayout = true; Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = BackgroundColor; ((Graphic)obj).raycastTarget = false; VerticalLayoutGroup obj2 = val.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj2).padding = new RectOffset(8, 8, 6, 6); ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ContentSizeFitter val4 = val.AddComponent<ContentSizeFitter>(); val4.horizontalFit = (FitMode)0; val4.verticalFit = (FitMode)2; CanvasGroup val5 = val.AddComponent<CanvasGroup>(); val5.alpha = 0f; val5.interactable = false; val5.blocksRaycasts = false; GameObject val6 = new GameObject("Text", new Type[1] { typeof(RectTransform) }) { layer = val.layer }; val6.transform.SetParent((Transform)(object)val2, false); HGTextMeshProUGUI val7 = val6.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)val7).fontSize = 15f; ((TMP_Text)val7).richText = true; ((TMP_Text)val7).enableWordWrapping = true; ((TMP_Text)val7).alignment = (TextAlignmentOptions)257; ((Graphic)val7).color = Color.white; ((Graphic)val7).raycastTarget = false; ZoneHudPanel zoneHudPanel = val.AddComponent<ZoneHudPanel>(); zoneHudPanel.rectTransform = val2; zoneHudPanel.canvasGroup = val5; zoneHudPanel.fitter = val4; zoneHudPanel.label = (TextMeshProUGUI)(object)val7; zoneHudPanel.icon = icon; zoneHudPanel.iconRectTransform = (RectTransform)((Component)icon).transform; Canvas componentInParent = ((Component)icon).GetComponentInParent<Canvas>(); zoneHudPanel.canvasRectTransform = ((!Object.op_Implicit((Object)(object)componentInParent)) ? ((RectTransform)null) : ((RectTransform)((Component)componentInParent.rootCanvas).transform)); return zoneHudPanel; } public void Hide() { visible = false; } public void Show(ZoneInfo zone, string disabledCause) { visible = true; SetMode(Mode.Zone); if ((Object)(object)zone.Zone != (Object)(object)describedZone) { describedZone = zone.Zone; outcome = ZoneScanner.DescribeOutcome(zone.Zone, out keepsStageCount); textDirty = true; } int num = (zone.IsStageStart ? Mathf.Max(0, Mathf.CeilToInt(zone.WindowRemaining * 10f)) : (-1)); if (textDirty || num != shownWindowTenths || disabledCause != shownDisabledCause) { textDirty = false; shownWindowTenths = num; shownDisabledCause = disabledCause; ((TMP_Text)label).text = BuildText(num, disabledCause); } } public void ShowIndicator(int zoneCount, bool pageDisabled) { visible = true; SetMode(Mode.Indicator); if (textDirty || zoneCount != shownIndicatorCount || pageDisabled != shownIndicatorDisabled) { textDirty = false; shownIndicatorCount = zoneCount; shownIndicatorDisabled = pageDisabled; string text = ((zoneCount == 1) ? "Sacrifice zone on this stage" : (zoneCount + " sacrifice zones on this stage")); ((TMP_Text)label).text = "<size=90%><color=#C38BFF>" + text + "</color>" + (pageDisabled ? " <color=#FF5A5A>(page disabled)</color>" : "") + "</size>"; } } private void SetMode(Mode newMode) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (newMode != mode) { mode = newMode; textDirty = true; if (mode == Mode.Zone) { fitter.horizontalFit = (FitMode)0; rectTransform.sizeDelta = new Vector2(260f, rectTransform.sizeDelta.y); ((TMP_Text)label).enableWordWrapping = true; } else { fitter.horizontalFit = (FitMode)2; ((TMP_Text)label).enableWordWrapping = false; } } } private string BuildText(int windowTenths, string disabledCause) { string text = ((disabledCause == null) ? "<color=#C38BFF><b>REINCARNATION READY</b></color>" : ("<color=#FF5A5A><b>REINCARNATION DISABLED</b></color>\n<color=#FF5A5A>" + disabledCause + "</color>")); text = text + "\n<b>" + outcome + "</b>"; if (keepsStageCount) { text += "\n<size=85%><color=#A0A0A0>Stage count unchanged</color></size>"; } if (windowTenths >= 0) { float num = (float)windowTenths / 10f; string text2 = ((num <= 5f) ? "#FF5A5A" : ((num <= 10f) ? "#FFC24D" : "#E6D9FF")); text = text + "\n<color=" + text2 + ">Window closes in " + num.ToString("0.0") + "s</color>"; } return text; } private void LateUpdate() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) PluginConfig settings = ReincarnationDisplayPlugin.Settings; ((Transform)rectTransform).localScale = Vector3.one * settings.PanelScale.Value; float num = (visible ? 1f : 0f); if (visible || canvasGroup.alpha > 0f) { float contentTop = GetContentTop(); Rect rect = iconRectTransform.rect; float num2 = contentTop - ((Rect)(ref rect)).yMax; rectTransform.anchoredPosition = new Vector2(0f, num2 + settings.PanelOffsetY.Value); KeepOnScreen(); } canvasGroup.alpha = Mathf.MoveTowards(canvasGroup.alpha, num, Time.unscaledDeltaTime / 0.15f); } private float GetContentTop() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Rect rect = iconRectTransform.rect; float num = Mathf.Max(((Rect)(ref rect)).yMax, MeasureTop((Transform)(object)iconRectTransform)); Transform val = (Object.op_Implicit((Object)(object)icon) ? icon.extraDisplayHolder : null); if (Object.op_Implicit((Object)(object)val) && !val.IsChildOf((Transform)(object)iconRectTransform)) { num = Mathf.Max(num, MeasureTop(val)); } return num; } private float MeasureTop(Transform node) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) float num = float.NegativeInfinity; if ((Object)(object)node == (Object)(object)rectTransform || !((Component)node).gameObject.activeInHierarchy) { return num; } RectTransform val = (RectTransform)(object)((node is RectTransform) ? node : null); if (val != null) { bool num2 = Object.op_Implicit((Object)(object)((Component)val).GetComponent<RectMask2D>()) || Object.op_Implicit((Object)(object)((Component)val).GetComponent<Mask>()); Graphic component = ((Component)val).GetComponent<Graphic>(); if (num2 || (Object.op_Implicit((Object)(object)component) && ((Behaviour)component).enabled)) { val.GetWorldCorners(corners); num = Mathf.Max(((Transform)iconRectTransform).InverseTransformPoint(corners[1]).y, ((Transform)iconRectTransform).InverseTransformPoint(corners[2]).y); } if (num2) { return num; } } for (int i = 0; i < node.childCount; i++) { num = Mathf.Max(num, MeasureTop(node.GetChild(i))); } return num; } private void KeepOnScreen() { //IL_004f: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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) if (!Object.op_Implicit((Object)(object)canvasRectTransform)) { return; } Transform parent = ((Transform)rectTransform).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (val != null) { rectTransform.GetWorldCorners(corners); canvasRectTransform.GetWorldCorners(canvasCorners); float num = 4f * ((Transform)canvasRectTransform).lossyScale.x; float num2 = 0f; if (corners[2].x > canvasCorners[2].x - num) { num2 = canvasCorners[2].x - num - corners[2].x; } else if (corners[0].x < canvasCorners[0].x + num) { num2 = canvasCorners[0].x + num - corners[0].x; } if (num2 != 0f && ((Transform)val).lossyScale.x > 0f) { RectTransform obj = rectTransform; obj.anchoredPosition += new Vector2(num2 / ((Transform)val).lossyScale.x, 0f); } } } } internal enum PageState { None, Usable, Disabled } internal enum ZoneShape { Tube, Sphere, Box, Everywhere, Unknown } internal struct ZoneInfo { public CursedBookSacrificeZone Zone; public ZoneShape Shape; public Vector3 Center; public float Radius; public Vector3 HalfExtents; public bool PlayerInside; public bool IsStageStart; public float WindowRemaining; } internal static class ZoneScanner { private const int ChampRushPageRequirement = 3; private const int ProvidencePageRequirement = 6; private const float EverywhereRadius = 10000f; private static readonly List<SceneDef> rerollCandidates = new List<SceneDef>(); private static SceneDef rerollCandidatesScene; private static Run rerollCandidatesRun; private static readonly List<SceneDef> sceneBuffer = new List<SceneDef>(); public static PageState GetPageState(CharacterBody body) { ItemDef pageDie = Items.PageDie; if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)pageDie)) { return PageState.None; } if (!Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive) { return PageState.None; } Inventory inventory = body.inventory; if (!Object.op_Implicit((Object)(object)inventory) || inventory.GetItemCountTotal(pageDie) <= 0) { return PageState.None; } if (inventory.GetItemCountEffective(pageDie) <= 0) { return PageState.Disabled; } return PageState.Usable; } public static string DescribeDisabledCause(CharacterBody body) { ItemDef roamingItemDisable = Items.RoamingItemDisable; Inventory val = (Object.op_Implicit((Object)(object)body) ? body.inventory : null); if (Object.op_Implicit((Object)(object)roamingItemDisable) && Object.op_Implicit((Object)(object)val) && val.GetItemCountTotal(roamingItemDisable) > 0) { return "Disabled by " + Language.GetString(roamingItemDisable.nameToken); } return "Page is disabled"; } public static bool HasReadyBuff(CharacterBody body) { BuffDef cursedBookReadyForSacrifice = Buffs.CursedBookReadyForSacrifice; if (Object.op_Implicit((Object)(object)cursedBookReadyForSacrifice) && Object.op_Implicit((Object)(object)body)) { return body.HasBuff(cursedBookReadyForSacrifice); } return false; } public static int Scan(CharacterBody body, List<ZoneInfo> results) { //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) //IL_006c: Unknown result type (might be due to invalid IL or missing references) int totalPageCountFromTeam = Util.GetTotalPageCountFromTeam((TeamIndex)1, true, true); Vector3 corePosition = body.corePosition; int num = -1; foreach (CursedBookSacrificeZone instance in CursedBookSacrificeZone.instanceList) { if (!IsValid(instance, totalPageCountFromTeam)) { continue; } ZoneInfo item = Describe(instance); if (!item.IsStageStart || !(item.WindowRemaining <= 0f) || !ReincarnationDisplayPlugin.Settings.HideStageStartZoneAfterWindow.Value) { item.PlayerInside = instance.zone.IsInBounds(corePosition); if (item.PlayerInside && num < 0) { num = results.Count; } results.Add(item); } } return num; } private static bool IsValid(CursedBookSacrificeZone zone, int teamPageCount) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)zone) || !((Component)zone).gameObject.activeInHierarchy) { return false; } if (zone.isDisabled || !zone.runFlagConditionResult) { return false; } IZone zone2 = zone.zone; Object val = (Object)(object)((zone2 is Object) ? zone2 : null); if (val == null || !Object.op_Implicit(val)) { return false; } if ((int)zone.behaviour == 0 && !HasPossibleDestination(zone)) { return false; } return teamPageCount >= RequiredPageCount(zone.pageRequirement); } private static int RequiredPageCount(PageRequirements requirement) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)requirement != 1) { if ((int)requirement == 2) { return Util.ScalePageRequirement(6); } return 0; } return Util.ScalePageRequirement(3); } private static bool HasPossibleDestination(CursedBookSacrificeZone zone) { if (zone.useRerollSceneInstead) { return GetRerollCandidates().Count > 0; } if (zone.useNextSceneInstead) { if (NetworkServer.active) { return Object.op_Implicit((Object)(object)Run.instance.nextStageScene); } return true; } if (!zone.useExplicitSceneInstead) { GetCollectionCandidates(zone, sceneBuffer); return sceneBuffer.Count > 0; } if (Object.op_Implicit((Object)(object)zone.explicitScene)) { return CanPickStage(zone.explicitScene); } return false; } private static ZoneInfo Describe(CursedBookSacrificeZone zone) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) ZoneInfo result = new ZoneInfo { Zone = zone, Shape = ZoneShape.Unknown, Center = ((Component)zone).transform.position }; IZone zone2 = zone.zone; VerticalTubeZone val = (VerticalTubeZone)(object)((zone2 is VerticalTubeZone) ? zone2 : null); if (val == null) { SphereZone val2 = (SphereZone)(object)((zone2 is SphereZone) ? zone2 : null); if (val2 == null) { BoxZone val3 = (BoxZone)(object)((zone2 is BoxZone) ? zone2 : null); if (val3 != null) { result.Shape = (val3.isInverted ? ZoneShape.Everywhere : ZoneShape.Box); result.Center = ((Component)val3).transform.position; result.HalfExtents = ((Component)val3).transform.lossyScale * 0.5f; } } else { result.Shape = ((!val2.isInverted && !(val2.radius >= 10000f)) ? ZoneShape.Sphere : ZoneShape.Everywhere); result.Center = ((Component)val2).transform.position; result.Radius = val2.radius; } } else { result.Shape = ((val.radius >= 10000f) ? ZoneShape.Everywhere : ZoneShape.Tube); result.Center = ((Component)val).transform.position; result.Radius = val.radius; } result.IsStageStart = IsStageStartZone(zone); if (result.IsStageStart) { result.WindowRemaining = GetWindowRemaining(zone); } return result; } private static float GetWindowRemaining(CursedBookSacrificeZone zone) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) float num; if (!Object.op_Implicit((Object)(object)Stage.instance)) { num = 0f; } else { FixedTimeStamp entryTime = Stage.instance.entryTime; num = ((FixedTimeStamp)(ref entryTime)).timeSince; } float num2 = num; Timer component = ((Component)zone).GetComponent<Timer>(); if (!Object.op_Implicit((Object)(object)component)) { return ReincarnationDisplayPlugin.Settings.StageStartWindowSeconds.Value - num2; } float num3 = (component.timerRunning ? (component.duration - component.stopwatch) : 0f); if (!NetworkServer.active && Object.op_Implicit((Object)(object)Stage.instance)) { num3 = Mathf.Min(num3, component.duration - num2); } return num3; } private static bool IsStageStartZone(CursedBookSacrificeZone zone) { if (zone.useRerollSceneInstead) { return true; } DLC4SacrificeZoneSpawner instance = DLC4SacrificeZoneSpawner.instance; GameObject val = ((Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.reincarnateCard)) ? instance.reincarnateCard.prefab : null); if (Object.op_Implicit((Object)(object)val)) { return ((Object)((Component)zone).gameObject).name.StartsWith(((Object)val).name); } return false; } public static string DescribeOutcome(CursedBookSacrificeZone zone, out bool keepsStageCount) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 keepsStageCount = zone.ShouldPreventStageCounterIncrement; if ((int)zone.behaviour == 1) { keepsStageCount = false; return "Opens the Veil of Memory"; } if (zone.useRerollSceneInstead) { keepsStageCount = false; return "Reroll stage " + (Run.instance.stageClearCount + 1); } if (zone.useNextSceneInstead) { return "Continues to the next stage"; } if (!zone.useExplicitSceneInstead) { GetCollectionCandidates(zone, sceneBuffer); if (sceneBuffer.Count == 1) { return "Destination: " + SceneName(sceneBuffer[0]); } if (Object.op_Implicit((Object)(object)zone.sceneTierCollection)) { return "Continues to the next stage"; } if (!Object.op_Implicit((Object)(object)zone.sceneCollection) || !((Object)zone.sceneCollection).name.Contains("Trial")) { return "Continues to a random stage"; } return "Enters a random Winnowing trial"; } if (!Object.op_Implicit((Object)(object)zone.explicitScene)) { return "Unknown destination"; } return "Destination: " + SceneName(zone.explicitScene); } private static List<SceneDef> GetRerollCandidates() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) SceneDef mostRecentSceneDef = SceneCatalog.mostRecentSceneDef; if ((Object)(object)mostRecentSceneDef == (Object)(object)rerollCandidatesScene && (Object)(object)Run.instance == (Object)(object)rerollCandidatesRun) { return rerollCandidates; } rerollCandidates.Clear(); rerollCandidatesScene = mostRecentSceneDef; rerollCandidatesRun = Run.instance; if (!Object.op_Implicit((Object)(object)mostRecentSceneDef)) { return rerollCandidates; } Enumerator<SceneDef> enumerator = SceneCatalog.allSceneDefs.GetEnumerator(); try { while (enumerator.MoveNext()) { SceneDef current = enumerator.Current; if (Object.op_Implicit((Object)(object)current) && (Object)(object)current != (Object)(object)mostRecentSceneDef && current.stageOrder == mostRecentSceneDef.stageOrder && CanPickStage(current)) { rerollCandidates.Add(current); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return rerollCandidates; } internal static void GetCollectionCandidates(CursedBookSacrificeZone zone, List<SceneDef> results) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) results.Clear(); Run instance = Run.instance; SceneCollection val = (Object.op_Implicit((Object)(object)zone.sceneTierCollection) ? zone.sceneTierCollection.GetSceneCollection(instance.stageClearCountInCurrentLoop + 1) : zone.sceneCollection); if (!Object.op_Implicit((Object)(object)val)) { return; } Enumerator<SceneEntry> enumerator = val.sceneEntries.GetEnumerator(); try { while (enumerator.MoveNext()) { SceneEntry current = enumerator.Current; SceneDef val2 = current.sceneDef; if (!Object.op_Implicit((Object)(object)val2)) { continue; } if (!CanPickStage(val2)) { val2 = current.fallbackSceneDef; if (!Object.op_Implicit((Object)(object)val2)) { continue; } } if (Object.op_Implicit((Object)(object)val2.loopedSceneDef) && instance.loopClearCount > 0) { val2 = val2.loopedSceneDef; } if (!results.Contains(val2)) { results.Add(val2); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } private static bool CanPickStage(SceneDef def) { if (Object.op_Implicit((Object)(object)def.requiredExpansion)) { return Run.instance.IsExpansionEnabled(def.requiredExpansion); } return true; } internal static string SceneName(SceneDef def) { string text = Language.GetString(def.nameToken); if (!string.IsNullOrEmpty(text) && !(text == def.nameToken)) { return text; } return def.cachedName; } } internal sealed class ZoneWorldRings : MonoBehaviour { private sealed class Ring { public GameObject Root; public readonly List<LineRenderer> Lines = new List<LineRenderer>(); public int ActiveLines; public ZoneShape Shape; public Vector3 Center; public float Radius; public Vector3 HalfExtents; public bool Built; public bool Seen; } private const float LineWidth = 0.25f; private const float InsideLineWidth = 0.4f; private const float GroundOffset = 0.2f; private const float RebuildTolerance = 0.05f; private const float SampleSpacing = 1f; private const int MinSamples = 32; private const int MaxSamples = 512; private const float RayAbove = 15f; private const float RayBelow = 30f; private const float MaxStepHeight = 0.75f; private const float MaxSlope = 1.2f; private const int MinPieceSamples = 3; private const float FloorSearchReach = 20f; private const float FloorSearchLift = 1f; private const float MinCrossSectionRadius = 0.5f; private static readonly Color RingColor = new Color(0.76f, 0.55f, 1f, 0.45f); private static readonly Color InsideRingColor = new Color(0.86f, 0.66f, 1f, 0.95f); private readonly Dictionary<CursedBookSacrificeZone, Ring> rings = new Dictionary<CursedBookSacrificeZone, Ring>(); private readonly Stack<Ring> pool = new Stack<Ring>(); private readonly List<CursedBookSacrificeZone> staleZones = new List<CursedBookSacrificeZone>(); private readonly Vector3[] samples = (Vector3[])(object)new Vector3[512]; private readonly bool[] sampleOnFloor = new bool[512]; private readonly List<Vector3> piece = new List<Vector3>(); private Material material; public static ZoneWorldRings Create() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return new GameObject("ReincarnationZoneRings").AddComponent<ZoneWorldRings>(); } private void Awake() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown Material defaultSpriteMaterial = GetDefaultSpriteMaterial(); if (!Object.op_Implicit((Object)(object)defaultSpriteMaterial)) { ReincarnationDisplayPlugin.Log.LogError((object)"No usable line material found; world rings are disabled."); } else { material = new Material(defaultSpriteMaterial); } } private void OnDestroy() { if (Object.op_Implicit((Object)(object)material)) { Object.Destroy((Object)(object)material); } } private static Material GetDefaultSpriteMaterial() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("ReincarnationMaterialProbe"); try { return ((Renderer)val.AddComponent<SpriteRenderer>()).sharedMaterial; } finally { Object.DestroyImmediate((Object)(object)val); } } public void Clear() { if (rings.Count == 0) { return; } foreach (Ring value in rings.Values) { Release(value); } rings.Clear(); } public void UpdateRings(List<ZoneInfo> zones, Vector3 viewer, float maxDistance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)material)) { return; } foreach (Ring value2 in rings.Values) { value2.Seen = false; } foreach (ZoneInfo zone in zones) { if ((zone.Shape == ZoneShape.Tube || zone.Shape == ZoneShape.Sphere || zone.Shape == ZoneShape.Box) && !(DistanceToEdge(zone, viewer) > maxDistance)) { if (!rings.TryGetValue(zone.Zone, out var value)) { value = Rent(); rings.Add(zone.Zone, value); } value.Seen = true; if (NeedsRebuild(value, zone)) { Rebuild(value, zone, viewer); } Color val = (zone.PlayerInside ? InsideRingColor : RingColor); float widthMultiplier = (zone.PlayerInside ? 0.4f : 0.25f); for (int i = 0; i < value.ActiveLines; i++) { LineRenderer obj = value.Lines[i]; obj.startColor = val; obj.endColor = val; obj.widthMultiplier = widthMultiplier; } } } foreach (KeyValuePair<CursedBookSacrificeZone, Ring> ring in rings) { if (!ring.Value.Seen) { staleZones.Add(ring.Key); } } foreach (CursedBookSacrificeZone staleZone in staleZones) { Release(rings[staleZone]); rings.Remove(staleZone); } staleZones.Clear(); } private static float DistanceToEdge(ZoneInfo zone, Vector3 viewer) { //IL_0002: 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) //IL_0014: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(viewer.x - zone.Center.x, viewer.z - zone.Center.z); if (zone.Shape == ZoneShape.Box) { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(Mathf.Max(0f, Mathf.Abs(val.x) - zone.HalfExtents.x), Mathf.Max(0f, Mathf.Abs(val.y) - zone.HalfExtents.z)); return ((Vector2)(ref val2)).magnitude; } return Mathf.Max(0f, ((Vector2)(ref val)).magnitude - zone.Radius); } private static bool NeedsRebuild(Ring ring, ZoneInfo zone) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (ring.Built && ring.Shape == zone.Shape) { Vector3 val = ring.Center - zone.Center; if (!(((Vector3)(ref val)).sqrMagnitude > 0.0025000002f) && !(Mathf.Abs(ring.Radius - zone.Radius) > 0.05f)) { val = ring.HalfExtents - zone.HalfExtents; return ((Vector3)(ref val)).sqrMagnitude > 0.0025000002f; } } return true; } private void Rebuild(Ring ring, ZoneInfo zone, Vector3 viewer) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) ring.Built = true; ring.Shape = zone.Shape; ring.Center = zone.Center; ring.Radius = zone.Radius; ring.HalfExtents = zone.HalfExtents; int num = ((zone.Shape == ZoneShape.Box) ? SampleBox(zone) : SampleCircle(zone, viewer)); ring.ActiveLines = 0; if (num > 0) { EmitPieces(ring, num); } for (int i = ring.ActiveLines; i < ring.Lines.Count; i++) { ((Component)ring.Lines[i]).gameObject.SetActive(false); } } private int SampleCircle(ZoneInfo zone, Vector3 viewer) { //IL_006c: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) float num = zone.Radius; float num2; if (zone.Shape == ZoneShape.Sphere) { num2 = (TryGetGroundY(zone.Center, Mathf.Max(num, 20f), out var groundY) ? groundY : zone.Center.y); float num3 = zone.Center.y - num2; num = Mathf.Sqrt(Mathf.Max(0f, num * num - num3 * num3)); if (num < 0.5f) { return 0; } } else { num2 = (TryGetGroundY(zone.Center, 20f, out var groundY2) ? groundY2 : viewer.y); } int num4 = Mathf.Clamp(Mathf.CeilToInt(MathF.PI * 2f * num / 1f), 32, 512); for (int i = 0; i < num4; i++) { float num5 = (float)i * (MathF.PI * 2f / (float)num4); SampleAt(i, zone.Center.x + Mathf.Cos(num5) * num, zone.Center.z + Mathf.Sin(num5) * num, num2); } return num4; } private int SampleBox(ZoneInfo zone) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) Vector3 halfExtents = zone.HalfExtents; float groundY; float floorY = (TryGetGroundY(zone.Center, Mathf.Max(halfExtents.y, 20f), out groundY) ? groundY : zone.Center.y); Vector2[] array = (Vector2[])(object)new Vector2[4] { new Vector2(0f - halfExtents.x, 0f - halfExtents.z), new Vector2(halfExtents.x, 0f - halfExtents.z), new Vector2(halfExtents.x, halfExtents.z), new Vector2(0f - halfExtents.x, halfExtents.z) }; float num = 4f * (halfExtents.x + halfExtents.z); int num2 = Mathf.Clamp(Mathf.CeilToInt(num / 1f), 32, 512); int num3 = 0; for (int i = 0; i < 4; i++) { Vector2 val = array[i]; Vector2 val2 = array[(i + 1) % 4]; int num4; if (i >= 3) { num4 = num2 - num3; } else { float num5 = num2; Vector2 val3 = val2 - val; num4 = Mathf.Max(1, Mathf.RoundToInt(num5 * ((Vector2)(ref val3)).magnitude / num)); } int num6 = num4; for (int j = 0; j < num6; j++) { if (num3 >= num2) { break; } Vector2 val4 = Vector2.Lerp(val, val2, (float)j / (float)num6); SampleAt(num3++, zone.Center.x + val4.x, zone.Center.z + val4.y, floorY); } } return num3; } private void SampleAt(int index, float x, float z, float floorY) { //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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = new Vector3(x, floorY + 15f, z); Vector3 down = Vector3.down; LayerIndex world = LayerIndex.world; RaycastHit val2 = default(RaycastHit); bool flag = Physics.Raycast(val, down, ref val2, 45f, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1); samples[index] = new Vector3(x, (flag ? ((RaycastHit)(ref val2)).point.y : floorY) + 0.2f, z); sampleOnFloor[index] = flag; } private void EmitPieces(Ring ring, int count) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) int num = -1; for (int i = 0; i < count; i++) { if (!Joined(i, (i + 1) % count)) { num = i; break; } } if (num < 0) { piece.Clear(); for (int j = 0; j < count; j++) { piece.Add(samples[j]); } AddLine(ring, closed: true); return; } piece.Clear(); for (int k = 1; k <= count; k++) { int num2 = (num + k) % count; if (sampleOnFloor[num2]) { piece.Add(samples[num2]); } if (!Joined(num2, (num2 + 1) % count)) { if (piece.Count >= 3) { AddLine(ring, closed: false); } piece.Clear(); } } } private bool Joined(int a, int b) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) if (!sampleOnFloor[a] || !sampleOnFloor[b]) { return false; } Vector3 val = samples[a]; Vector3 val2 = samples[b]; Vector2 val3 = new Vector2(val2.x - val.x, val2.z - val.z); float magnitude = ((Vector2)(ref val3)).magnitude; return Mathf.Abs(val2.y - val.y) <= 0.75f + magnitude * 1.2f; } private void AddLine(Ring ring, bool closed) { LineRenderer val; if (ring.ActiveLines < ring.Lines.Count) { val = ring.Lines[ring.ActiveLines]; } else { val = CreateLine(ring.Root.transform); ring.Lines.Add(val); } ring.ActiveLines++; ((Component)val).gameObject.SetActive(true); val.loop = closed; val.positionCount = piece.Count; val.SetPositions(piece.ToArray()); } private static bool TryGetGroundY(Vector3 center, float reach, out float groundY) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) Vector3 val = center + Vector3.up * 1f; Vector3 down = Vector3.down; float num = reach + 1f; LayerIndex world = LayerIndex.world; RaycastHit val2 = default(RaycastHit); if (!Physics.Raycast(val, down, ref val2, num, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { Vector3 val3 = center + Vector3.up * reach; Vector3 down2 = Vector3.down; float num2 = reach - 1f; world = LayerIndex.world; if (!Physics.Raycast(val3, down2, ref val2, num2, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask), (QueryTriggerInteraction)1)) { groundY = center.y; return false; } } groundY = ((RaycastHit)(ref val2)).point.y; return true; } private Ring Rent() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (pool.Count > 0) { Ring ring = pool.Pop(); ring.Built = false; ring.Root.SetActive(true); return ring; } GameObject val = new GameObject("Ring"); val.transform.SetParent(((Component)this).transform, false); return new Ring { Root = val }; } private LineRenderer CreateLine(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Piece"); val.transform.SetParent(parent, false); LineRenderer obj = val.AddComponent<LineRenderer>(); ((Renderer)obj).sharedMaterial = material; obj.useWorldSpace = true; obj.numCornerVertices = 2; obj.numCapVertices = 2; obj.alignment = (LineAlignment)0; obj.textureMode = (LineTextureMode)0; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return obj; } private void Release(Ring ring) { ring.Root.SetActive(false); pool.Push(ring); } } internal static class PluginVersionInfo { public const string Version = "1.0.1"; } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }