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 ComfortMagicBubbles v1.0.0
ComfortMagicBubbles/ComfortMagicBubbles.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ComfortMagicBubbles.Bootstrap; using ComfortMagicBubbles.Configuration; using ComfortMagicBubbles.Core; using ComfortMagicBubbles.Features.Bubbles.Domain; using ComfortMagicBubbles.Features.Bubbles.Infrastructure; using ComfortMagicBubbles.Integrations.Harmony; using ComfortMagicBubbles.Integrations.Unity; using ComfortMagicBubbles.Integrations.Valheim; using ComfortMagicBubbles.Presentation.Hub.Registration; using ComfortMagicBubbles.Presentation.Hub.ViewModels; using ComfortMagicBubbles.Ui; using HarmonyLib; using Jotunn.Utils; using KydlCore.Common; using KydlCore.Core; using KydlCore.Features.Diagnostics.Contracts; using KydlCore.Features.Hub.Contracts; using KydlCore.Ui; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UIElements; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ComfortMagicBubbles.Ui { internal sealed class BubbleRowPage { internal string Label { get; } internal bool UseGame { get; } internal string Hex { get; } internal Action<bool> OnUseGame { get; } internal Action<string> OnHex { get; } internal BubbleRowPage(string label, bool useGame, string hex, Action<bool> onUseGame, Action<string> onHex) { Label = label; UseGame = useGame; Hex = hex; OnUseGame = onUseGame ?? ((Action<bool>)delegate { }); OnHex = onHex ?? ((Action<string>)delegate { }); } } internal sealed class BubbleKindPage { internal string Title { get; } internal int Opacity { get; } internal bool DistortionFree { get; } internal int Reflection { get; } internal Action<int> OnOpacity { get; } internal Action<bool> OnDistortionFree { get; } internal Action<int> OnReflection { get; } internal IList<BubbleRowPage> Rows { get; } internal PatternPage Pattern { get; } internal BubbleKindPage(string title, int opacity, bool distortionFree, Action<int> onOpacity, Action<bool> onDistortionFree, IList<BubbleRowPage> rows, int reflection = 100, Action<int> onReflection = null, PatternPage pattern = null) { Pattern = pattern; Title = title; Opacity = opacity; DistortionFree = distortionFree; Reflection = reflection; OnReflection = onReflection ?? ((Action<int>)delegate { }); OnOpacity = onOpacity ?? ((Action<int>)delegate { }); OnDistortionFree = onDistortionFree ?? ((Action<bool>)delegate { }); Rows = rows ?? new List<BubbleRowPage>(); } } internal sealed class PatternPage { internal IList<string> Choices { get; } internal string Chosen { get; } internal int Strength { get; } internal int Speed { get; } internal int Density { get; } internal Action<string> OnChosen { get; } internal Action<int> OnStrength { get; } internal Action<int> OnSpeed { get; } internal Action<int> OnDensity { get; } internal PatternPage(IList<string> choices, string chosen, int strength, int speed, int density, Action<string> onChosen, Action<int> onStrength, Action<int> onSpeed, Action<int> onDensity) { Choices = choices ?? new List<string>(); Chosen = chosen; Strength = strength; Speed = speed; Density = density; OnChosen = onChosen ?? ((Action<string>)delegate { }); OnStrength = onStrength ?? ((Action<int>)delegate { }); OnSpeed = onSpeed ?? ((Action<int>)delegate { }); OnDensity = onDensity ?? ((Action<int>)delegate { }); } } internal sealed class FadeNumberPage { internal string Label { get; } internal float Min { get; } internal float Max { get; } internal bool WholeNumbers { get; } internal float Value { get; } internal Action<float> OnValue { get; } internal FadeNumberPage(string label, float min, float max, bool wholeNumbers, float value, Action<float> onValue) { Label = label; Min = min; Max = max; WholeNumbers = wholeNumbers; Value = value; OnValue = onValue ?? ((Action<float>)delegate { }); } } internal sealed class FadeRulePage { internal string Title { get; } internal string Note { get; } internal bool On { get; } internal int FadeToPercent { get; } internal Action<bool> OnOn { get; } internal Action<int> OnFadeTo { get; } internal IList<FadeNumberPage> Numbers { get; } internal FadeRulePage(string title, string note, bool on, int fadeToPercent, Action<bool> onOn, Action<int> onFadeTo, IList<FadeNumberPage> numbers) { Title = title; Note = note; On = on; FadeToPercent = fadeToPercent; OnOn = onOn ?? ((Action<bool>)delegate { }); OnFadeTo = onFadeTo ?? ((Action<int>)delegate { }); Numbers = numbers ?? new List<FadeNumberPage>(); } } internal sealed class AutoFadePage { internal bool Enabled { get; } internal Action<bool> OnEnabled { get; } internal FadeNumberPage Blend { get; } internal IList<FadeRulePage> Rules { get; } internal AutoFadePage(bool enabled, Action<bool> onEnabled, FadeNumberPage blend, IList<FadeRulePage> rules) { Enabled = enabled; Blend = blend; OnEnabled = onEnabled ?? ((Action<bool>)delegate { }); Rules = rules ?? new List<FadeRulePage>(); } } internal sealed class BubblesPage { internal IList<BubbleKindPage> Kinds { get; } internal AutoFadePage AutoFade { get; } internal BubblesPage(IList<BubbleKindPage> kinds, AutoFadePage autoFade = null) { Kinds = kinds ?? new List<BubbleKindPage>(); AutoFade = autoFade; } } internal static class BubblesTabView { internal static VisualElement Build(Func<string, string> text, BubblesPage page) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown VisualElement val = new VisualElement(); if (page.Kinds.Count == 0) { val.Add((VisualElement)(object)UiControls.Note("No bubble kinds.")); return val; } List<string> titles = new List<string>(); foreach (BubbleKindPage kind in page.Kinds) { titles.Add(kind.Title); } VisualElement content = new VisualElement(); val.Add(UiControls.Heading("Bubble")); val.Add((VisualElement)(object)UiControls.Dropdown((IList<string>)titles, titles[0], (Func<string, string>)((string t) => t), (Action<string>)delegate(string chosen) { Fill(content, page.Kinds[Math.Max(0, titles.IndexOf(chosen))]); })); val.Add(content); Fill(content, page.Kinds[0]); if (page.AutoFade != null) { val.Add(AutoFade(page.AutoFade)); } UiLog.Verbose("BubblesTabView: built, " + page.Kinds.Count + " kind(s), auto-fade block " + (page.AutoFade != null)); return val; } private static VisualElement AutoFade(AutoFadePage fade) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown VisualElement val = new VisualElement(); val.Add(UiControls.Heading("Auto-fade")); val.Add((VisualElement)(object)UiControls.Note("Bubbles dim by themselves where they block the view. When several rules apply, the strongest fade wins. 'Fade to' = how much of the normal look is left (100 = not at all, 0 = invisible).")); val.Add(UiControls.Toggle("Auto-fade on", fade.Enabled, fade.OnEnabled)); if (fade.Blend != null) { val.Add(Number(fade.Blend)); } foreach (FadeRulePage rule in fade.Rules) { val.Add(UiControls.Heading(rule.Title)); if (!string.IsNullOrEmpty(rule.Note)) { val.Add((VisualElement)(object)UiControls.Note(rule.Note)); } val.Add(UiControls.Toggle("Enabled", rule.On, rule.OnOn)); val.Add(UiControls.Row("Fade to (%)", UiControls.Slider(0f, 100f, (float)rule.FadeToPercent, "0", (Action<float>)delegate(float v) { rule.OnFadeTo((int)Math.Round(v)); }))); foreach (FadeNumberPage number in rule.Numbers) { val.Add(Number(number)); } } return val; } private static VisualElement Number(FadeNumberPage number) { return UiControls.Row(number.Label, UiControls.Slider(number.Min, number.Max, number.Value, number.WholeNumbers ? "0" : "0.0", number.OnValue)); } private static void Fill(VisualElement content, BubbleKindPage kind) { content.Clear(); content.Add(UiControls.Heading("Look - " + kind.Title)); content.Add((VisualElement)(object)UiControls.Note("The same for every bubble of this weapon, whoever wears it, and for every colour below.")); content.Add(UiControls.Row("Opacity (%)", UiControls.Slider(0f, 100f, (float)kind.Opacity, "0", (Action<float>)delegate(float v) { kind.OnOpacity((int)Math.Round(v)); }))); content.Add(UiControls.Toggle("Distortion-free (no bending of the view)", kind.DistortionFree, kind.OnDistortionFree)); content.Add(UiControls.Row("Reflection (%)", UiControls.Slider(0f, 100f, (float)kind.Reflection, "0", (Action<float>)delegate(float v) { kind.OnReflection((int)Math.Round(v)); }))); if (kind.Pattern != null) { AddPattern(content, kind); } content.Add(UiControls.Heading("Colour - " + kind.Title)); content.Add((VisualElement)(object)UiControls.Note("An extra on top of the look. 'Default color' ON keeps the game's own colour for that target. 'Pick colour', then Apply: the colour is saved and 'Default color' is turned off, so it is used. The small square shows the saved colour (faded while 'Default color' is on).")); foreach (BubbleRowPage row in kind.Rows) { content.Add(Row(row)); } } private static void AddPattern(VisualElement content, BubbleKindPage kind) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) PatternPage pattern = kind.Pattern; content.Add(UiControls.Heading("Pattern - " + kind.Title)); content.Add((VisualElement)(object)UiControls.Note("Draws a pattern on the bubble. It uses the colour you pick below (or its own colour while 'Default color' is on), the opacity, reflection and distortion settings above.")); VisualElement sliders = new VisualElement(); sliders.Add(UiControls.Row("Strength (%)", UiControls.Slider(0f, 200f, (float)pattern.Strength, "0", (Action<float>)delegate(float v) { pattern.OnStrength((int)Math.Round(v)); }))); sliders.Add(UiControls.Row("Speed (%)", UiControls.Slider(0f, 400f, (float)pattern.Speed, "0", (Action<float>)delegate(float v) { pattern.OnSpeed((int)Math.Round(v)); }))); sliders.Add(UiControls.Row("Density (%)", UiControls.Slider(25f, 400f, (float)pattern.Density, "0", (Action<float>)delegate(float v) { pattern.OnDensity((int)Math.Round(v)); }))); sliders.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)((pattern.Chosen == pattern.Choices[0]) ? 1 : 0)); content.Add(UiControls.Row("Pattern", (VisualElement)(object)UiControls.Dropdown(pattern.Choices, pattern.Chosen, (Func<string, string>)((string t) => t), (Action<string>)delegate(string chosen) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) pattern.OnChosen(chosen); sliders.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)((chosen == pattern.Choices[0]) ? 1 : 0)); }))); content.Add(sliders); } private static VisualElement Row(BubbleRowPage row) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_001e: 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_0066: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_00fe: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) VisualElement val = new VisualElement(); val.style.flexShrink = StyleFloat.op_Implicit(0f); string saved = row.Hex; string pending = row.Hex; bool useGame = row.UseGame; VisualElement swatch = new VisualElement(); swatch.style.width = StyleLength.op_Implicit(28f); swatch.style.height = StyleLength.op_Implicit(22f); swatch.style.flexShrink = StyleFloat.op_Implicit(0f); swatch.style.marginLeft = StyleLength.op_Implicit(6f); UiKit.Radius(swatch, 4f); UiKit.Borders(swatch, 1f, UiKit.Border); VisualElement toggleSlot = new VisualElement(); toggleSlot.style.flexShrink = StyleFloat.op_Implicit(0f); ShowToggle(useGame); ShowSwatch(); UiColorPicker picker = new UiColorPicker(saved, (Action<string>)delegate(string hex) { pending = hex; }, false); TextField hexField = UQueryExtensions.Q<TextField>(picker.Root, (string)null, (string)null); VisualElement panel = new VisualElement(); panel.style.flexShrink = StyleFloat.op_Implicit(0f); panel.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1); panel.Add(picker.Root); bool open = false; Button val2 = UiControls.Button("Apply", (Action)delegate { string text2 = ((hexField == null) ? null : ((BaseField<string>)(object)hexField).value?.Trim()); if (!string.IsNullOrEmpty(text2)) { string text3 = (text2.StartsWith("#") ? text2 : ("#" + text2)); Color val4 = default(Color); if (text3.Length == 7 && ColorUtility.TryParseHtmlString(text3, ref val4)) { pending = text3.ToUpperInvariant(); } } row.OnHex(pending); saved = pending; if (useGame) { useGame = false; row.OnUseGame(obj: false); ShowToggle(on: false); } ShowSwatch(); SetOpen(value: false); }, true); panel.Add(UiControls.Line((VisualElement[])(object)new VisualElement[2] { (VisualElement)val2, (VisualElement)UiControls.Note("Saves the colour and turns 'Default color' off for this row.") })); Button val3 = UiControls.Button("Pick colour", (Action)delegate { SetOpen(!open); }, false); string text = row.Label.Replace(" ", ""); ((VisualElement)val3).name = "CmbPick_" + text; ((VisualElement)val2).name = "CmbApply_" + text; if (hexField != null) { ((VisualElement)hexField).name = "CmbHex_" + text; } val.Add(UiControls.Row(row.Label, UiControls.Line((VisualElement[])(object)new VisualElement[3] { toggleSlot, (VisualElement)val3, swatch }))); val.Add(panel); return val; void SetOpen(bool value) { //IL_0024: 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) open = value; Color val4 = default(Color); if (open && ColorUtility.TryParseHtmlString(saved, ref val4)) { picker.Set(val4); pending = saved; } panel.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)(!open)); } void ShowSwatch() { //IL_001a: 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_0044: Unknown result type (might be due to invalid IL or missing references) Color val4 = default(Color); if (ColorUtility.TryParseHtmlString(saved, ref val4)) { swatch.style.backgroundColor = StyleColor.op_Implicit(val4); } swatch.style.opacity = StyleFloat.op_Implicit(useGame ? 0.35f : 1f); swatch.tooltip = saved + (useGame ? " (not used while 'Default color' is on)" : ""); } void ShowToggle(bool on) { toggleSlot.Clear(); toggleSlot.Add(UiControls.Toggle("Default color", on, (Action<bool>)delegate(bool v) { useGame = v; row.OnUseGame(v); ShowSwatch(); })); } } } internal sealed class DetailGroup { internal readonly string Title; internal readonly List<DetailRow> Rows = new List<DetailRow>(); internal DetailGroup(string title) { Title = title ?? ""; } internal DetailRow Add(string label, string value, string maxValue = "") { DetailRow detailRow = new DetailRow(label, value, maxValue); Rows.Add(detailRow); return detailRow; } public override string ToString() { return Title + " (" + Rows.Count + " rows)"; } } internal sealed class DetailRow { internal readonly string Label; internal readonly string Value; internal readonly string MaxValue; internal bool HasMax => MaxValue.Length > 0; internal DetailRow(string label, string value, string maxValue = "") { Label = label ?? ""; Value = value ?? ""; MaxValue = maxValue ?? ""; } public override string ToString() { return Label + " = " + Value + (HasMax ? (" -> " + MaxValue) : ""); } } internal static class DetailsView { private const float LabelWidth = 210f; private const float ValueWidth = 140f; internal static VisualElement Build(IList<DetailGroup> groups, string qualityHeader, string maxQualityHeader) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) VisualElement val = new VisualElement { name = "kydl-details" }; val.style.flexShrink = StyleFloat.op_Implicit(0f); int num = 0; if (groups != null) { foreach (DetailGroup group in groups) { val.Add(UiControls.Heading(group.Title)); bool flag = false; foreach (DetailRow row in group.Rows) { if (row.HasMax) { flag = true; break; } } if (flag) { val.Add(ColumnHeader(qualityHeader, maxQualityHeader)); } foreach (DetailRow row2 in group.Rows) { val.Add(StatRow(row2, flag)); num++; } } } UiLog.Verbose("DetailsView: " + (groups?.Count ?? 0) + " group(s), " + num + " row(s)"); return val; } private static VisualElement ColumnHeader(string q, string max) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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) VisualElement obj = RowBox(); obj.Add((VisualElement)(object)Cell("", 210f, UiKit.TextDim, 18f)); obj.Add((VisualElement)(object)Cell(q ?? "", 140f, UiKit.TextDim, 18f)); obj.Add((VisualElement)(object)Cell(max ?? "", 140f, UiKit.TextDim, 18f)); return obj; } private static VisualElement StatRow(DetailRow row, bool blockHasMax) { //IL_0012: 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_006f: Unknown result type (might be due to invalid IL or missing references) VisualElement val = RowBox(); val.Add((VisualElement)(object)Cell(row.Label, 210f, UiKit.TextDim, 22f)); val.Add((VisualElement)(object)Cell(row.Value, (blockHasMax && row.HasMax) ? 140f : (-1f), UiKit.Text, 22f)); if (blockHasMax && row.HasMax) { val.Add((VisualElement)(object)Cell(row.MaxValue, 140f, UiKit.Gold, 22f)); } return val; } private static VisualElement RowBox() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0027: 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_003c: 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_0051: 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_0067: Expected O, but got Unknown VisualElement val = new VisualElement(); val.style.flexDirection = StyleEnum<FlexDirection>.op_Implicit((FlexDirection)2); val.style.alignItems = StyleEnum<Align>.op_Implicit((Align)1); val.style.flexShrink = StyleFloat.op_Implicit(0f); val.style.marginTop = StyleLength.op_Implicit(2f); val.style.marginBottom = StyleLength.op_Implicit(2f); return val; } private static Label Cell(string content, float width, Color color, float size) { //IL_0002: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Label val = UiKit.Label(content, size, color, false); ((VisualElement)val).style.whiteSpace = StyleEnum<WhiteSpace>.op_Implicit((WhiteSpace)0); if (width >= 0f) { ((VisualElement)val).style.width = StyleLength.op_Implicit(width); ((VisualElement)val).style.flexShrink = StyleFloat.op_Implicit(0f); } else { ((VisualElement)val).style.flexGrow = StyleFloat.op_Implicit(1f); ((VisualElement)val).style.flexShrink = StyleFloat.op_Implicit(1f); } return val; } } internal interface IModelScene : IDisposable { Texture Texture { get; } bool Show(string modelId); bool Resize(int widthPx, int heightPx); bool Render(float yawDeg, float pitchDeg, float zoom, float panX, float panY, float panZ); } internal sealed class ModelViewerRig : IModelScene, IDisposable { internal static readonly Vector3 Park = new Vector3(0f, -1500f, 0f); internal const float FieldOfView = 30f; private const float LogEverySeconds = 0.5f; private readonly Func<string, GameObject> _makeModel; private readonly ViewerSettings _settings; private readonly Action<string> _log; private readonly int _layer; private readonly string _rigName; private GameObject _root; private GameObject _pivot; private GameObject _model; private Camera _camera; private readonly List<Light> _lights = new List<Light>(); private RenderTexture _texture; private string _modelId; private float _halfWidth; private float _halfHeight; private float _radius; private float _lastLog = -100f; private float _lastLightLog = -100f; private int _renders; public Texture Texture => (Texture)(object)_texture; internal unsafe ModelViewerRig(Func<string, GameObject> makeModel, int layer, ViewerSettings settings, Color background, Action<string> log, string rigName = "Kydl_ViewerRig") { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00b9: 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_00d3: Expected O, but got Unknown //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) _makeModel = makeModel; _settings = settings ?? new ViewerSettings(); _log = log; _layer = Mathf.Clamp(layer, 0, 31); _rigName = (string.IsNullOrEmpty(rigName) ? "Kydl_ViewerRig" : rigName); if (_layer != layer) { Log("ModelViewerRig: layer " + layer + " is outside 0..31, using " + _layer); } _root = new GameObject(_rigName); _root.transform.position = Park; _pivot = new GameObject("Pivot"); _pivot.transform.SetParent(_root.transform, false); GameObject val = new GameObject("Camera"); val.transform.SetParent(_root.transform, false); _camera = val.AddComponent<Camera>(); ((Behaviour)_camera).enabled = false; _camera.cullingMask = 1 << _layer; _camera.clearFlags = (CameraClearFlags)2; _camera.backgroundColor = background; _camera.fieldOfView = 30f; _camera.nearClipPlane = 0.02f; _camera.farClipPlane = 200f; _camera.allowHDR = false; _camera.useOcclusionCulling = false; _camera.renderingPath = (RenderingPath)1; AddLight(val.transform, "KeyLight", new Vector3(25f, 30f, 0f), _settings.KeyLight); AddLight(val.transform, "FillLight", new Vector3(-10f, -45f, 0f), _settings.FillLight); string[] obj = new string[10] { "ModelViewerRig: made at ", V(Park), ", layer ", _layer.ToString(), ", fov ", 30f.ToString(), " deg, background ", null, null, null }; Color val2 = background; obj[7] = ((object)(*(Color*)(&val2))/*cast due to .constrained prefix*/).ToString(); obj[8] = ", "; obj[9] = _settings?.ToString(); Log(string.Concat(obj)); } private void AddLight(Transform parent, string name, Vector3 euler, float intensity) { //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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0049: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localRotation = Quaternion.Euler(euler); Light val2 = val.AddComponent<Light>(); val2.type = (LightType)1; val2.intensity = intensity; val2.color = new Color(1f, 0.96f, 0.9f); val2.shadows = (LightShadows)0; val2.cullingMask = 1 << _layer; val2.renderMode = (LightRenderMode)1; ((Behaviour)val2).enabled = false; _lights.Add(val2); } public bool Show(string modelId) { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: 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_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0243: 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_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null) { Log("ModelViewerRig: Show(" + modelId + ") after Dispose - ignored"); return false; } if ((Object)(object)_model != (Object)null) { _model.SetActive(false); Object.Destroy((Object)(object)_model); _model = null; } _modelId = modelId; if (string.IsNullOrEmpty(modelId)) { Log("ModelViewerRig: no model to show"); return false; } GameObject val = null; Log("ModelViewerRig: making the model '" + modelId + "'"); try { val = ((_makeModel != null) ? _makeModel(modelId) : null); } catch (Exception ex) { Log("ModelViewerRig: making the model '" + modelId + "' failed: " + ex.GetType().Name + ": " + ex.Message); } if ((Object)(object)val == (Object)null) { Log("ModelViewerRig: no model for '" + modelId + "' (model maker gave null)"); return false; } _model = val; _pivot.transform.localRotation = Quaternion.identity; _model.transform.SetParent(_pivot.transform, false); _model.transform.localPosition = Vector3.zero; _model.transform.localRotation = Quaternion.identity; int num = Prepare(_model); if (num == 0) { Log("ModelViewerRig: model '" + modelId + "' has no renderers - nothing to see"); return false; } Bounds val2 = WorldBounds(_model); Vector3 size = ((Bounds)(ref val2)).size; Quaternion localRotation = Quaternion.identity; string text = "X"; if (size.y >= size.x && size.y >= size.z) { localRotation = Quaternion.Euler(0f, 0f, -90f); text = "Y"; } else if (size.z >= size.x && size.z >= size.y) { localRotation = Quaternion.Euler(0f, 90f, 0f); text = "Z"; } _model.transform.localRotation = localRotation; Bounds val3 = WorldBounds(_model); Transform transform = _model.transform; transform.position -= ((Bounds)(ref val3)).center - _pivot.transform.position; Bounds val4 = WorldBounds(_model); _halfWidth = ((Bounds)(ref val4)).extents.x; _halfHeight = Mathf.Max(((Bounds)(ref val4)).extents.y, ((Bounds)(ref val4)).extents.z); Vector3 extents = ((Bounds)(ref val4)).extents; _radius = ((Vector3)(ref extents)).magnitude; Log("ModelViewerRig: showing '" + modelId + "': " + num + " renderer(s), size " + V(((Bounds)(ref val2)).size) + " m, longest axis " + text + " laid across, centre offset " + V(((Bounds)(ref val4)).center - _pivot.transform.position) + " m, half width " + F(_halfWidth) + " / height " + F(_halfHeight) + " / radius " + F(_radius) + " m"); return true; } private int Prepare(GameObject model) { int num = 0; int num2 = 0; Transform[] componentsInChildren = model.GetComponentsInChildren<Transform>(true); int i; for (i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = _layer; } Renderer[] componentsInChildren2 = model.GetComponentsInChildren<Renderer>(true); foreach (Renderer obj in componentsInChildren2) { obj.shadowCastingMode = (ShadowCastingMode)0; obj.receiveShadows = false; SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((obj is SkinnedMeshRenderer) ? obj : null); if ((Object)(object)val != (Object)null) { val.updateWhenOffscreen = true; } num++; } Collider[] componentsInChildren3 = model.GetComponentsInChildren<Collider>(true); for (i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].enabled = false; num2++; } string[] obj2 = new string[9] { "ModelViewerRig: prepared model '", ((Object)model).name, "': ", num.ToString(), " renderer(s) on layer ", null, null, null, null }; i = _layer; obj2[5] = i.ToString(); obj2[6] = ", "; obj2[7] = num2.ToString(); obj2[8] = " collider(s) off"; Log(string.Concat(obj2)); return num; } private static Bounds WorldBounds(GameObject go) { //IL_0025: 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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length == 0) { return new Bounds(go.transform.position, Vector3.zero); } Bounds bounds = componentsInChildren[0].bounds; for (int i = 1; i < componentsInChildren.Length; i++) { ((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds); } return bounds; } public bool Resize(int widthPx, int heightPx) { //IL_0099: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown if ((Object)(object)_root == (Object)null) { Log("ModelViewerRig: Resize after Dispose - ignored"); return false; } int num = Mathf.Clamp(widthPx, 16, 4096); int num2 = Mathf.Clamp(heightPx, 16, 4096); if ((Object)(object)_texture != (Object)null && ((Texture)_texture).width == num && ((Texture)_texture).height == num2) { return true; } if ((Object)(object)_texture != (Object)null) { _camera.targetTexture = null; _texture.Release(); Object.Destroy((Object)(object)_texture); } _texture = new RenderTexture(num, num2, 24, (RenderTextureFormat)0) { name = _rigName + "_Texture", antiAliasing = 4 }; _texture.Create(); _camera.targetTexture = _texture; Log("ModelViewerRig: texture " + num + "x" + num2 + " px (asked " + widthPx + "x" + heightPx + ")"); return true; } public bool Render(float yawDeg, float pitchDeg, float zoom, float panX, float panY, float panZ) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_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) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_root == (Object)null || (Object)(object)_texture == (Object)null) { Log("ModelViewerRig: Render skipped (" + (((Object)(object)_root == (Object)null) ? "disposed" : "no texture yet") + ")"); return false; } float num = (float)((Texture)_texture).width / (float)((Texture)_texture).height; float num2 = ViewerMath.FitDistance(_halfWidth, _halfHeight, _radius, 30f, num, _settings.Margin); float num3 = num2 / Mathf.Max(0.01f, zoom); float num4 = 2f * num2 * Mathf.Tan((float)Math.PI / 12f); Vector3 val = new Vector3(panX, panY, panZ) * num4; ViewerMath.Orbit(yawDeg, pitchDeg, num3, out var x, out var y, out var z); Vector3 val2 = _pivot.transform.position + val; ((Component)_camera).transform.position = val2 + new Vector3(x, y, z); ((Component)_camera).transform.LookAt(val2, Vector3.up); _camera.nearClipPlane = Mathf.Clamp(num3 - ((Vector3)(ref val)).magnitude - _radius * 1.2f, 0.01f, 0.5f); RenderLit(); _renders++; float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _lastLog >= 0.5f) { _lastLog = realtimeSinceStartup; Log("ModelViewerRig: render #" + _renders + " of " + (_modelId ?? "nothing") + ": yaw " + F(yawDeg) + " / pitch " + F(pitchDeg) + " deg, zoom x" + F(zoom) + ", fit " + F(num2) + " m, distance " + F(num3) + " m, aspect " + F(num) + ", pan " + V(val) + " m (" + V(new Vector3(panX, panY, panZ)) + " view heights of " + F(num4) + " m), near " + F(_camera.nearClipPlane) + " m, model " + (((Object)(object)_model != (Object)null) ? "shown" : "none")); } return true; } private unsafe void RenderLit() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0210: 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) AmbientMode ambientMode = RenderSettings.ambientMode; Color ambientLight = RenderSettings.ambientLight; float ambientIntensity = RenderSettings.ambientIntensity; bool fog = RenderSettings.fog; try { if (_lights.Count > 0 && (Object)(object)_lights[0] != (Object)null) { _lights[0].intensity = _settings.KeyLight; } if (_lights.Count > 1 && (Object)(object)_lights[1] != (Object)null) { _lights[1].intensity = _settings.FillLight; } for (int i = 0; i < _lights.Count; i++) { if ((Object)(object)_lights[i] != (Object)null) { ((Behaviour)_lights[i]).enabled = true; } } RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = new Color(_settings.Ambient, _settings.Ambient * 0.95f, _settings.Ambient * 0.9f); RenderSettings.ambientIntensity = 1f; RenderSettings.fog = false; _camera.Render(); } finally { int num = 0; for (int j = 0; j < _lights.Count; j++) { if ((Object)(object)_lights[j] != (Object)null) { ((Behaviour)_lights[j]).enabled = false; if (((Behaviour)_lights[j]).enabled) { num++; } } } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - _lastLightLog >= 2f) { _lastLightLog = realtimeSinceStartup; string[] obj = new string[12] { "ModelViewerRig: lights ", _lights.Count.ToString(), " switched on for this render only, ", num.ToString(), " still on after it (expect 0); ambient put back to ", ((object)(*(AmbientMode*)(&ambientMode))/*cast due to .constrained prefix*/).ToString(), " / ", null, null, null, null, null }; Color val = ambientLight; obj[7] = ((object)(*(Color*)(&val))/*cast due to .constrained prefix*/).ToString(); obj[8] = " x"; obj[9] = ambientIntensity.ToString(); obj[10] = ", fog "; obj[11] = fog.ToString(); Log(string.Concat(obj)); } RenderSettings.ambientMode = ambientMode; RenderSettings.ambientLight = ambientLight; RenderSettings.ambientIntensity = ambientIntensity; RenderSettings.fog = fog; } } public void Dispose() { if (!((Object)(object)_root == (Object)null)) { if ((Object)(object)_camera != (Object)null) { _camera.targetTexture = null; } if ((Object)(object)_texture != (Object)null) { _texture.Release(); Object.Destroy((Object)(object)_texture); _texture = null; } Object.Destroy((Object)(object)_root); _root = null; _model = null; _camera = null; Log("ModelViewerRig: disposed after " + _renders + " render(s)"); } } private static string F(float v) { return v.ToString("0.###", CultureInfo.InvariantCulture); } private static string V(Vector3 v) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) return "(" + F(v.x) + ", " + F(v.y) + ", " + F(v.z) + ")"; } private void Log(string s) { if (_log != null) { _log(s); } } } internal static class ModelViewportView { private sealed class Viewport { private readonly IModelScene _scene; private readonly ViewerOrbit _orbit; private readonly Image _image; private readonly VisualElement _frame; private readonly string _modelId; private bool _dragging; private bool _panning; private int _dragButton = -1; private Vector2 _last; private int _pointer = -1; internal Viewport(string title, string modelId, IModelScene scene, ViewerSettings settings, VisualElement frame, string hint, string reset) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: 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_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Expected O, but got Unknown //IL_0202: 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_022c: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) Viewport viewport = this; _scene = scene; _frame = frame; _modelId = modelId; _orbit = new ViewerOrbit(settings, (Action<string>)UiLog.Verbose); _image = new Image { name = "kydl-viewport-image", scaleMode = (ScaleMode)0 }; ((VisualElement)_image).style.position = StyleEnum<Position>.op_Implicit((Position)1); ((VisualElement)_image).style.left = StyleLength.op_Implicit(0f); ((VisualElement)_image).style.top = StyleLength.op_Implicit(0f); ((VisualElement)_image).style.right = StyleLength.op_Implicit(0f); ((VisualElement)_image).style.bottom = StyleLength.op_Implicit(0f); frame.Add((VisualElement)(object)_image); Label val = UiKit.Label(title ?? "", 24f, UiKit.Gold, true); ((VisualElement)val).style.position = StyleEnum<Position>.op_Implicit((Position)1); ((VisualElement)val).style.left = StyleLength.op_Implicit(10f); ((VisualElement)val).style.top = StyleLength.op_Implicit(6f); ((VisualElement)val).pickingMode = (PickingMode)1; frame.Add((VisualElement)(object)val); Label val2 = UiKit.Label(hint ?? "", 18f, UiKit.TextDim, false); ((VisualElement)val2).style.position = StyleEnum<Position>.op_Implicit((Position)1); ((VisualElement)val2).style.left = StyleLength.op_Implicit(10f); ((VisualElement)val2).style.bottom = StyleLength.op_Implicit(8f); ((VisualElement)val2).pickingMode = (PickingMode)1; frame.Add((VisualElement)(object)val2); VisualElement val3 = new VisualElement { name = "kydl-viewport-buttons" }; val3.style.position = StyleEnum<Position>.op_Implicit((Position)1); val3.style.right = StyleLength.op_Implicit(6f); val3.style.bottom = StyleLength.op_Implicit(4f); val3.style.flexDirection = StyleEnum<FlexDirection>.op_Implicit((FlexDirection)2); val3.Add((VisualElement)(object)UiControls.Button("+", (Action)delegate { viewport.Changed(viewport._orbit.StepZoom(1f), "zoom in button"); }, false)); val3.Add((VisualElement)(object)UiControls.Button("-", (Action)delegate { viewport.Changed(viewport._orbit.StepZoom(-1f), "zoom out button"); }, false)); val3.Add((VisualElement)(object)UiControls.Button(reset ?? "Reset", (Action)delegate { viewport.Changed(viewport._orbit.Reset(), "reset button"); }, false)); frame.Add(val3); ((CallbackEventHandler)_image).RegisterCallback<PointerDownEvent>((EventCallback<PointerDownEvent>)OnDown, (TrickleDown)0); ((CallbackEventHandler)_image).RegisterCallback<PointerMoveEvent>((EventCallback<PointerMoveEvent>)OnMove, (TrickleDown)0); ((CallbackEventHandler)_image).RegisterCallback<PointerUpEvent>((EventCallback<PointerUpEvent>)OnUp, (TrickleDown)0); ((CallbackEventHandler)_image).RegisterCallback<PointerCaptureOutEvent>((EventCallback<PointerCaptureOutEvent>)delegate { viewport.EndDrag("capture lost"); }, (TrickleDown)0); ((CallbackEventHandler)frame).RegisterCallback<WheelEvent>((EventCallback<WheelEvent>)OnWheel, (TrickleDown)0); ((CallbackEventHandler)frame).RegisterCallback<GeometryChangedEvent>((EventCallback<GeometryChangedEvent>)delegate { viewport.OnResized(frame); }, (TrickleDown)0); ((CallbackEventHandler)frame).RegisterCallback<DetachFromPanelEvent>((EventCallback<DetachFromPanelEvent>)delegate { viewport.Teardown(); }, (TrickleDown)0); bool flag = _scene.Show(_modelId); _orbit.Reset(); UiLog.Verbose("ModelViewportView: 3D viewport built for '" + _modelId + "', model " + (flag ? "shown" : "NOT shown (see the ModelViewerRig lines above)") + " (" + settings?.ToString() + ")"); } private void OnDown(PointerDownEvent e) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) if (((PointerEventBase<PointerDownEvent>)(object)e).button == 0 || ((PointerEventBase<PointerDownEvent>)(object)e).button == 1) { if (_dragging) { UiLog.Verbose("ModelViewportView: button " + ((PointerEventBase<PointerDownEvent>)(object)e).button + " pressed during a " + (_panning ? "pan" : "rotate") + " drag (button " + _dragButton + ") - ignored"); return; } _dragging = true; _panning = ((PointerEventBase<PointerDownEvent>)(object)e).button == 1; _dragButton = ((PointerEventBase<PointerDownEvent>)(object)e).button; _pointer = ((PointerEventBase<PointerDownEvent>)(object)e).pointerId; _last = new Vector2(((PointerEventBase<PointerDownEvent>)(object)e).position.x, ((PointerEventBase<PointerDownEvent>)(object)e).position.y); PointerCaptureHelper.CapturePointer((IEventHandler)(object)_image, ((PointerEventBase<PointerDownEvent>)(object)e).pointerId); ((EventBase)e).StopPropagation(); UiLog.Verbose("ModelViewportView: " + (_panning ? "pan" : "rotate") + " drag started at " + P(_last) + " (button " + ((PointerEventBase<PointerDownEvent>)(object)e).button + ", pointer " + ((PointerEventBase<PointerDownEvent>)(object)e).pointerId + ", frame " + FrameHeightPx().ToString("0", CultureInfo.InvariantCulture) + " UI px high)"); } } private void OnMove(PointerMoveEvent e) { //IL_001a: 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_0034: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_007e: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!_dragging || ((PointerEventBase<PointerMoveEvent>)(object)e).pointerId != _pointer) { return; } Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(((PointerEventBase<PointerMoveEvent>)(object)e).position.x, ((PointerEventBase<PointerMoveEvent>)(object)e).position.y); Vector2 val2 = val - _last; _last = val; if (!(((Vector2)(ref val2)).sqrMagnitude <= 0f)) { if (_panning ? _orbit.Pan(val2.x, val2.y, FrameHeightPx()) : _orbit.Drag(val2.x, val2.y)) { Draw(null); } ((EventBase)e).StopPropagation(); } } private void OnUp(PointerUpEvent e) { if (((PointerEventBase<PointerUpEvent>)(object)e).button == _dragButton && ((PointerEventBase<PointerUpEvent>)(object)e).pointerId == _pointer) { if (PointerCaptureHelper.HasPointerCapture((IEventHandler)(object)_image, ((PointerEventBase<PointerUpEvent>)(object)e).pointerId)) { PointerCaptureHelper.ReleasePointer((IEventHandler)(object)_image, ((PointerEventBase<PointerUpEvent>)(object)e).pointerId); } EndDrag("button " + ((PointerEventBase<PointerUpEvent>)(object)e).button + " released"); ((EventBase)e).StopPropagation(); } } private void EndDrag(string why) { if (_dragging) { _dragging = false; _pointer = -1; UiLog.Verbose("ModelViewportView: " + (_panning ? "pan" : "rotate") + " drag ended (" + why + "), view " + _orbit); _panning = false; _dragButton = -1; } } private float FrameHeightPx() { //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 contentRect = _frame.contentRect; return ((Rect)(ref contentRect)).height; } private void OnWheel(WheelEvent e) { //IL_0008: 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) Changed(_orbit.Wheel(e.delta.y), "wheel " + e.delta.y.ToString("0.##", CultureInfo.InvariantCulture)); ((EventBase)e).StopPropagation(); } private void OnResized(VisualElement frame) { //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) Rect contentRect = frame.contentRect; float num = PixelsPerPoint(); int num2 = Mathf.RoundToInt(((Rect)(ref contentRect)).width * num); int num3 = Mathf.RoundToInt(((Rect)(ref contentRect)).height * num); if (num2 < 16 || num3 < 16) { UiLog.Verbose("ModelViewportView: frame " + ((Rect)(ref contentRect)).width + "x" + ((Rect)(ref contentRect)).height + " UI px is too small (hidden tab?), no texture"); return; } UiLog.Verbose("ModelViewportView: frame " + ((Rect)(ref contentRect)).width.ToString("0", CultureInfo.InvariantCulture) + "x" + ((Rect)(ref contentRect)).height.ToString("0", CultureInfo.InvariantCulture) + " UI px x " + num.ToString("0.###", CultureInfo.InvariantCulture) + " = " + num2 + "x" + num3 + " screen px"); if (_scene.Resize(num2, num3)) { _image.image = _scene.Texture; } Draw("resized"); } private static float PixelsPerPoint() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) PanelSettings settings = UiKit.Settings; if (!((Object)(object)settings == (Object)null) && (int)settings.scaleMode == 2) { Vector2Int referenceResolution = settings.referenceResolution; if (((Vector2Int)(ref referenceResolution)).y > 0) { float num = (((Object)(object)settings.targetTexture != (Object)null) ? ((Texture)settings.targetTexture).height : Screen.height); referenceResolution = settings.referenceResolution; return Mathf.Clamp(num / (float)((Vector2Int)(ref referenceResolution)).y, 0.25f, 8f); } } return 1f; } private void Changed(bool changed, string why) { if (changed) { Draw(why); return; } UiLog.Verbose("ModelViewportView: " + why + " - view unchanged (" + _orbit?.ToString() + ")"); } private void Draw(string why) { bool flag = _scene.Render(_orbit.Yaw, _orbit.Pitch, _orbit.Zoom, _orbit.PanX, _orbit.PanY, _orbit.PanZ); ((VisualElement)_image).MarkDirtyRepaint(); if (why != null) { UiLog.Verbose("ModelViewportView: drawn after " + why + " (" + _orbit?.ToString() + ")" + (flag ? "" : " - scene did not render")); } } private void Teardown() { _image.image = null; _scene.Dispose(); UiLog.Verbose("ModelViewportView: viewport closed, 3D scene of '" + _modelId + "' disposed"); } private static string P(Vector2 v) { return "(" + v.x.ToString("0", CultureInfo.InvariantCulture) + ", " + v.y.ToString("0", CultureInfo.InvariantCulture) + ")"; } } internal static VisualElement Build(string title, string modelId, Func<IModelScene> makeScene, ViewerSettings settings, string hint, string reset, string unavailable) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_004a: 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) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_0114: 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_014f: Unknown result type (might be due to invalid IL or missing references) settings = settings ?? new ViewerSettings(); settings.Clamp((Action<string>)UiLog.Verbose); VisualElement val = new VisualElement { name = "kydl-viewport" }; val.style.flexShrink = StyleFloat.op_Implicit(0f); val.style.height = StyleLength.op_Implicit(settings.FrameHeight); val.style.marginTop = StyleLength.op_Implicit(10f); val.style.backgroundColor = StyleColor.op_Implicit(UiKit.Track); UiKit.Borders(val, 1f, UiKit.Border); UiKit.Radius(val, 4f); val.style.overflow = StyleEnum<Overflow>.op_Implicit((Overflow)1); IModelScene modelScene = null; try { modelScene = makeScene?.Invoke(); } catch (Exception ex) { UiLog.Error("ModelViewportView: making the 3D scene failed: " + ex.GetType().Name + ": " + ex.Message); } if (modelScene == null) { val.style.justifyContent = StyleEnum<Justify>.op_Implicit((Justify)1); val.style.alignItems = StyleEnum<Align>.op_Implicit((Align)2); val.Add((VisualElement)(object)UiKit.Label(title ?? "", 24f, UiKit.TextDim, true)); val.Add((VisualElement)(object)UiKit.Label(unavailable ?? "", 22f, UiKit.TextDim, false)); UiLog.Verbose("ModelViewportView: no 3D scene, showing the title '" + title + "' only"); return val; } new Viewport(title, modelId, modelScene, settings, val, hint, reset); return val; } } internal sealed class TabBar { private const float RailMargin = 18f; private readonly List<Button> _buttons = new List<Button>(); private readonly Action<int> _changed; private int _selected = -1; internal VisualElement Root { get; private set; } internal int Selected => _selected; internal TabBar(IList<string> names, int selected, Action<int> changed) { //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_0035: Expected O, but got Unknown //IL_0041: 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_0075: 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_00a9: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0195: 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_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) _changed = changed; Root = new VisualElement { name = "kydl-tabs" }; Root.style.flexDirection = StyleEnum<FlexDirection>.op_Implicit((FlexDirection)2); Root.style.flexShrink = StyleFloat.op_Implicit(0f); Root.style.marginLeft = StyleLength.op_Implicit(18f); Root.style.marginRight = StyleLength.op_Implicit(18f); Root.style.marginTop = StyleLength.op_Implicit(8f); Root.style.borderBottomWidth = StyleFloat.op_Implicit(1f); Root.style.borderBottomColor = StyleColor.op_Implicit(UiKit.Border); for (int i = 0; i < names.Count; i++) { int index = i; Button val = new Button((Action)delegate { Select(index); }) { text = names[i] }; ((VisualElement)val).style.fontSize = StyleLength.op_Implicit(21f); ((VisualElement)val).style.flexShrink = StyleFloat.op_Implicit(0f); ((VisualElement)val).style.marginLeft = StyleLength.op_Implicit(0f); ((VisualElement)val).style.marginRight = StyleLength.op_Implicit(4f); ((VisualElement)val).style.marginTop = StyleLength.op_Implicit(0f); ((VisualElement)val).style.marginBottom = StyleLength.op_Implicit(0f); UiKit.Pad((VisualElement)(object)val, 8f, 22f); ((VisualElement)val).style.borderTopWidth = StyleFloat.op_Implicit(0f); ((VisualElement)val).style.borderLeftWidth = StyleFloat.op_Implicit(0f); ((VisualElement)val).style.borderRightWidth = StyleFloat.op_Implicit(0f); ((VisualElement)val).style.borderBottomWidth = StyleFloat.op_Implicit(3f); UiKit.Radius((VisualElement)(object)val, 0f); UiKit.Fade((VisualElement)(object)val, new string[2] { "background-color", "color" }); ((CallbackEventHandler)val).RegisterCallback<PointerEnterEvent>((EventCallback<PointerEnterEvent>)delegate { Paint(index, hover: true); }, (TrickleDown)0); ((CallbackEventHandler)val).RegisterCallback<PointerLeaveEvent>((EventCallback<PointerLeaveEvent>)delegate { Paint(index, hover: false); }, (TrickleDown)0); _buttons.Add(val); Root.Add((VisualElement)(object)val); } Show(Mathf.Clamp(selected, 0, Math.Max(0, names.Count - 1))); UiLog.Verbose("TabBar: built with " + names.Count + " tab(s) [" + string.Join(", ", names) + "], selected " + _selected); } internal bool Select(int index) { if (index < 0 || index >= _buttons.Count) { UiLog.Verbose("TabBar: tab " + index + " does not exist (" + _buttons.Count + " tabs), selection stays " + _selected); return _selected == index; } if (index == _selected) { return _selected == index; } UiLog.Verbose("TabBar: tab " + _selected + " -> " + index + " ('" + ((TextElement)_buttons[index]).text + "')"); Show(index); if (_changed != null) { _changed(index); } return _selected == index; } private void Show(int index) { _selected = index; for (int i = 0; i < _buttons.Count; i++) { Paint(i, hover: false); } } private void Paint(int index, bool hover) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) Button obj = _buttons[index]; bool flag = index == _selected; ((VisualElement)obj).style.backgroundColor = StyleColor.op_Implicit(flag ? UiKit.PanelLight : (hover ? UiKit.PanelHover : Color.clear)); ((VisualElement)obj).style.color = StyleColor.op_Implicit(flag ? UiKit.Gold : (hover ? UiKit.Text : UiKit.TextDim)); ((VisualElement)obj).style.borderBottomColor = StyleColor.op_Implicit(flag ? UiKit.Gold : Color.clear); } } internal static class UiText { internal static readonly Dictionary<string, string> En = new Dictionary<string, string> { { "comfortmagicbubbles_menu_title", "ComfortMagicBubbles" }, { "comfortmagicbubbles_menu_footer", "Esc to close" }, { "comfortmagicbubbles_tab_settings", "Settings" } }; internal static string English(string key) { if (!En.TryGetValue(key, out var value)) { return key; } return value; } } internal static class ViewerMath { private const double Rad = Math.PI / 180.0; internal const float MinDistanceRadii = 1.5f; internal static float FitDistance(float halfWidth, float halfHeight, float radius, float verticalFovDeg, float aspect, float margin) { if (!(verticalFovDeg > 1f) || !(verticalFovDeg < 179f)) { verticalFovDeg = 30f; } if (!(aspect > 0.01f) || float.IsInfinity(aspect)) { aspect = 1f; } if (!(margin >= 0f) || float.IsInfinity(margin)) { margin = 0f; } if (!(radius > 0f) || float.IsInfinity(radius)) { radius = 0.5f; } halfWidth = ((halfWidth > 0f && !float.IsInfinity(halfWidth)) ? halfWidth : radius); halfHeight = ((halfHeight > 0f && !float.IsInfinity(halfHeight)) ? halfHeight : radius); double num = Math.Tan((double)verticalFovDeg * 0.5 * (Math.PI / 180.0)); double num2 = num * (double)aspect; double num3 = 1.0 + (double)margin; double val = (double)halfWidth * num3 / num2; double val2 = (double)halfHeight * num3 / num; return (float)Math.Max(radius * 1.5f, Math.Max(val, val2)); } internal static float ClampPitch(float pitch, float limit) { limit = Math.Max(0f, Math.Min(89f, float.IsNaN(limit) ? 0f : limit)); if (float.IsNaN(pitch)) { return 0f; } return Math.Max(0f - limit, Math.Min(limit, pitch)); } internal static float WrapYaw(float yaw) { if (float.IsNaN(yaw) || float.IsInfinity(yaw)) { return 0f; } double num = (double)yaw % 360.0; if (num > 180.0) { num -= 360.0; } if (num <= -180.0) { num += 360.0; } return (float)num; } internal static float StepZoom(float zoom, float steps, float factor, float min, float max) { if (!(min > 0f)) { min = 0.01f; } if (max < min) { max = min; } if (!(factor > 1f)) { factor = 1f; } if (!(zoom > 0f) || float.IsInfinity(zoom)) { zoom = 1f; } double val = (double)zoom * Math.Pow(factor, float.IsNaN(steps) ? 0f : steps); return (float)Math.Max(min, Math.Min(max, val)); } internal static void Orbit(float yawDeg, float pitchDeg, float distance, out float x, out float y, out float z) { double num = (double)yawDeg * (Math.PI / 180.0); double num2 = (double)pitchDeg * (Math.PI / 180.0); double num3 = (double)distance * Math.Cos(num2); x = (float)((0.0 - num3) * Math.Sin(num)); y = (float)((double)distance * Math.Sin(num2)); z = (float)((0.0 - num3) * Math.Cos(num)); } internal static void CameraAxes(float yawDeg, float pitchDeg, out float rx, out float ry, out float rz, out float ux, out float uy, out float uz) { double num = (double)yawDeg * (Math.PI / 180.0); double num2 = (double)pitchDeg * (Math.PI / 180.0); double num3 = Math.Sin(num); double num4 = Math.Cos(num); double num5 = Math.Sin(num2); double num6 = Math.Cos(num2); rx = (float)num4; ry = 0f; rz = (float)(0.0 - num3); ux = (float)(num5 * num3); uy = (float)num6; uz = (float)(num5 * num4); } internal static bool ClampLength(ref float x, ref float y, ref float z, float limit) { if (float.IsNaN(x) || float.IsNaN(y) || float.IsNaN(z)) { x = 0f; y = 0f; z = 0f; return true; } limit = (float.IsNaN(limit) ? 0f : Math.Max(0f, limit)); double num = Math.Sqrt((double)x * (double)x + (double)y * (double)y + (double)z * (double)z); if (num <= (double)limit) { return false; } double num2 = ((num > 0.0) ? ((double)limit / num) : 0.0); x = (float)((double)x * num2); y = (float)((double)y * num2); z = (float)((double)z * num2); return true; } } internal sealed class ViewerOrbit { private readonly ViewerSettings _settings; private const float Tiny = 1E-06f; private readonly Action<string> _log; internal float Yaw { get; private set; } internal float Pitch { get; private set; } internal float Zoom { get; private set; } internal float PanX { get; private set; } internal float PanY { get; private set; } internal float PanZ { get; private set; } private static bool Differs(float a, float b) { return !(Math.Abs(a - b) <= 1E-06f); } internal ViewerOrbit(ViewerSettings settings, Action<string> log = null) { _settings = settings ?? new ViewerSettings(); _log = log; Reset(); } internal bool Reset() { float num = ViewerMath.WrapYaw(_settings.StartYaw); float num2 = ViewerMath.ClampPitch(_settings.StartPitch, _settings.PitchLimit); bool flag = PanX != 0f || PanY != 0f || PanZ != 0f; bool flag2 = Differs(num, Yaw) || Differs(num2, Pitch) || Differs(Zoom, 1f) || flag; Yaw = num; Pitch = num2; Zoom = 1f; PanX = 0f; PanY = 0f; PanZ = 0f; Log("ViewerOrbit: reset to " + this?.ToString() + (flag2 ? "" : " (already there)")); return flag2; } internal bool Pan(float dx, float dy, float frameHeightPx) { if (float.IsNaN(dx) || float.IsNaN(dy)) { Log("ViewerOrbit: pan with NaN ignored"); return false; } if (!(frameHeightPx >= 1f) || float.IsInfinity(frameHeightPx)) { Log("ViewerOrbit: pan ignored, frame height " + F(frameHeightPx) + " px is not usable"); return false; } float num = _settings.PanSpeed / (frameHeightPx * Math.Max(0.01f, Zoom)); ViewerMath.CameraAxes(Yaw, Pitch, out var rx, out var ry, out var rz, out var ux, out var uy, out var uz); float x = PanX + ((0f - rx) * dx + ux * dy) * num; float y = PanY + ((0f - ry) * dx + uy * dy) * num; float z = PanZ + ((0f - rz) * dx + uz * dy) * num; bool flag = ViewerMath.ClampLength(ref x, ref y, ref z, _settings.PanLimit); int num2; if (!(Math.Abs(x - PanX) > 1E-06f) && !(Math.Abs(y - PanY) > 1E-06f)) { num2 = ((Math.Abs(z - PanZ) > 1E-06f) ? 1 : 0); if (num2 == 0) { if (flag) { Log("ViewerOrbit: pan at the limit (" + F(_settings.PanLimit) + " view heights), view " + this); } return (byte)num2 != 0; } } else { num2 = 1; } PanX = x; PanY = y; PanZ = z; return (byte)num2 != 0; } internal bool Drag(float dx, float dy) { if (float.IsNaN(dx) || float.IsNaN(dy)) { Log("ViewerOrbit: drag with NaN ignored"); return false; } float num = ViewerMath.WrapYaw(Yaw - dx * _settings.RotateSpeed); float num2 = ViewerMath.ClampPitch(Pitch + dy * _settings.RotateSpeed, _settings.PitchLimit); bool result = Differs(num, Yaw) || Differs(num2, Pitch); Yaw = num; Pitch = num2; return result; } internal bool StepZoom(float steps) { float num = ViewerMath.StepZoom(Zoom, steps, _settings.ZoomStep, _settings.ZoomMin, _settings.ZoomMax); bool flag = Differs(num, Zoom); Log("ViewerOrbit: zoom " + F(Zoom) + " -> " + F(num) + " (" + F(steps) + " step(s), range " + F(_settings.ZoomMin) + ".." + F(_settings.ZoomMax) + ")" + (flag ? "" : " - at the limit")); Zoom = num; return flag; } internal bool Wheel(float deltaY) { if (deltaY == 0f || float.IsNaN(deltaY)) { return false; } return StepZoom((deltaY > 0f) ? (-1f) : 1f); } private static string F(float v) { return v.ToString("0.##", CultureInfo.InvariantCulture); } public override string ToString() { return "yaw " + F(Yaw) + " deg, pitch " + F(Pitch) + " deg, zoom x" + F(Zoom) + ", pan (" + F(PanX) + ", " + F(PanY) + ", " + F(PanZ) + ") view heights"; } private void Log(string s) { if (_log != null) { _log(s); } } } internal sealed class ViewerSettings { internal const float RotateSpeedMin = 0.05f; internal const float RotateSpeedMax = 2f; internal const float RotateSpeedDefault = 0.4f; internal const float ZoomStepMin = 1.02f; internal const float ZoomStepMax = 2f; internal const float ZoomStepDefault = 1.2f; internal const float ZoomMaxMin = 1f; internal const float ZoomMaxMax = 20f; internal const float ZoomMaxDefault = 8f; internal const float ZoomMinMin = 0.2f; internal const float ZoomMinMax = 1f; internal const float ZoomMinDefault = 0.5f; internal const float PitchLimitMin = 0f; internal const float PitchLimitMax = 89f; internal const float PitchLimitDefault = 80f; internal const float FrameHeightMin = 200f; internal const float FrameHeightMax = 800f; internal const float FrameHeightDefault = 420f; internal const float MarginMin = 0f; internal const float MarginMax = 0.5f; internal const float MarginDefault = 0.08f; internal const float StartYawMin = -180f; internal const float StartYawMax = 180f; internal const float StartYawDefault = 20f; internal const float StartPitchMin = -89f; internal const float StartPitchMax = 89f; internal const float StartPitchDefault = 12f; internal const float PanSpeedMin = 0.2f; internal const float PanSpeedMax = 3f; internal const float PanSpeedDefault = 1f; internal const float PanLimitMin = 0f; internal const float PanLimitMax = 3f; internal const float PanLimitDefault = 0.8f; internal const float KeyLightMin = 0f; internal const float KeyLightMax = 2f; internal const float KeyLightDefault = 0.7f; internal const float FillLightMin = 0f; internal const float FillLightMax = 1.5f; internal const float FillLightDefault = 0.25f; internal const float AmbientMin = 0f; internal const float AmbientMax = 1f; internal const float AmbientDefault = 0.22f; internal float RotateSpeed = 0.4f; internal float ZoomStep = 1.2f; internal float ZoomMax = 8f; internal float ZoomMin = 0.5f; internal float PitchLimit = 80f; internal float FrameHeight = 420f; internal float Margin = 0.08f; internal float StartYaw = 20f; internal float StartPitch = 12f; internal float PanSpeed = 1f; internal float PanLimit = 0.8f; internal float KeyLight = 0.7f; internal float FillLight = 0.25f; internal float Ambient = 0.22f; internal int Clamp(Action<string> log = null) { int changed = 0; RotateSpeed = Fix("RotateSpeed", RotateSpeed, 0.05f, 2f, 0.4f, ref changed, log); ZoomStep = Fix("ZoomStep", ZoomStep, 1.02f, 2f, 1.2f, ref changed, log); ZoomMax = Fix("ZoomMax", ZoomMax, 1f, 20f, 8f, ref changed, log); ZoomMin = Fix("ZoomMin", ZoomMin, 0.2f, 1f, 0.5f, ref changed, log); PitchLimit = Fix("PitchLimit", PitchLimit, 0f, 89f, 80f, ref changed, log); FrameHeight = Fix("FrameHeight", FrameHeight, 200f, 800f, 420f, ref changed, log); Margin = Fix("Margin", Margin, 0f, 0.5f, 0.08f, ref changed, log); StartYaw = Fix("StartYaw", StartYaw, -180f, 180f, 20f, ref changed, log); StartPitch = Fix("StartPitch", StartPitch, -89f, 89f, 12f, ref changed, log); PanSpeed = Fix("PanSpeed", PanSpeed, 0.2f, 3f, 1f, ref changed, log); PanLimit = Fix("PanLimit", PanLimit, 0f, 3f, 0.8f, ref changed, log); KeyLight = Fix("KeyLight", KeyLight, 0f, 2f, 0.7f, ref changed, log); FillLight = Fix("FillLight", FillLight, 0f, 1.5f, 0.25f, ref changed, log); Ambient = Fix("Ambient", Ambient, 0f, 1f, 0.22f, ref changed, log); if (StartPitch > PitchLimit || StartPitch < 0f - PitchLimit) { float startPitch = StartPitch; StartPitch = Math.Max(0f - PitchLimit, Math.Min(PitchLimit, StartPitch)); changed++; log?.Invoke("ViewerSettings: StartPitch " + F(startPitch) + " is outside PitchLimit " + F(PitchLimit) + ", using " + F(StartPitch)); } log?.Invoke("ViewerSettings: " + this?.ToString() + " (" + changed + " value(s) put into range)"); return changed; } private static float Fix(string name, float v, float min, float max, float def, ref int changed, Action<string> log) { float num = ((float.IsNaN(v) || float.IsInfinity(v)) ? def : Math.Max(min, Math.Min(max, v))); if (!(Math.Abs(num - v) <= 1E-06f)) { changed++; log?.Invoke("ViewerSettings: " + name + " " + F(v) + " is outside " + F(min) + ".." + F(max) + ", using " + F(num)); } return num; } private static string F(float v) { return v.ToString("0.###", CultureInfo.InvariantCulture); } public override string ToString() { return "rotate " + F(RotateSpeed) + " deg/px, zoom step x" + F(ZoomStep) + ", zoom " + F(ZoomMin) + ".." + F(ZoomMax) + ", pitch limit " + F(PitchLimit) + " deg, frame " + F(FrameHeight) + " px, margin " + F(Margin) + ", start yaw " + F(StartYaw) + " / pitch " + F(StartPitch) + " deg, pan speed x" + F(PanSpeed) + ", pan limit " + F(PanLimit) + " view heights, light key " + F(KeyLight) + " / fill " + F(FillLight) + " / ambient " + F(Ambient); } } } namespace ComfortMagicBubbles.Testing { internal static class InGameTests { private static string Startup_ConfigBound() { if (ModSettings.EnableAll == null) { return "FAIL: ModSettings.Bind did not run (EnableAll is null)"; } if (!ModSettings.On) { return "SKIP: EnableAll is off in the config"; } return "PASS: EnableAll on"; } private static string Startup_FeaturesInstalled() { ModInstaller current = ModInstaller.Current; if (current == null) { return "FAIL: ModInstaller.Install did not run"; } int num = 0; foreach (IFeature item in current.Features.All) { if (current.Features.IsRunning(item.Id)) { num++; } } ModLog.Verbose("InGameTests: Startup_FeaturesInstalled " + current.Features.Count + " feature(s), " + num + " running"); if (current.Features.Count <= 0) { return "FAIL: no feature registered"; } return "PASS: " + current.Features.Count + " feature(s), " + num + " running"; } private static string Startup_CoreLoaded() { bool flag = Chainloader.PluginInfos.ContainsKey("com.kydldev.KydlCore"); ModLog.Verbose("InGameTests: Startup_CoreLoaded " + flag); if (!flag) { return "FAIL: com.kydldev.KydlCore is not loaded (this mod requires it)"; } return "PASS: com.kydldev.KydlCore is loaded"; } private static string World_PlayerPresent() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; ModLog.Verbose("InGameTests: World_PlayerPresent player " + (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerName() : "null")); if (!((Object)(object)localPlayer != (Object)null)) { return "FAIL: no local player 5 s after the world loaded"; } string playerName = localPlayer.GetPlayerName(); Vector3 position = ((Component)localPlayer).transform.position; return "PASS: " + playerName + " at " + ((Vector3)(ref position)).ToString("F1"); } } } namespace ComfortMagicBubbles.Testing.TestHooks { internal static class BubbleLookTestHooks { private const int ShotWidth = 480; private static float _baseWhiteness = -1f; private static float _baseLuma = -1f; [TestHook("ComfortMagicBubbles.bubble.whiteness")] private static string Whiteness(string who, string effect, string mark) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) string problem; MeshRenderer val = BubbleTestHooks.FindSphere(who, effect, out problem); if ((Object)(object)val == (Object)null) { return problem; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return BubbleTestHooks.Reason("no main camera"); } if (!Measure(main, val, out var whiteness, out var pixels, out var why, out var mean)) { return BubbleTestHooks.Reason(why); } CultureInfo invariantCulture = CultureInfo.InvariantCulture; if (mark == "base") { _baseWhiteness = whiteness; _baseLuma = Luma(mean); ModLog.Info($"BubbleLookTestHooks: whiteness base {whiteness:0.000} over {pixels} pixel(s)"); return whiteness.ToString("0.000", invariantCulture); } if (_baseWhiteness < 0f) { return BubbleTestHooks.Reason("no base measured (call with mark \"base\" first)"); } float num = whiteness - _baseWhiteness; ModLog.Info($"BubbleLookTestHooks: whiteness {whiteness:0.000} vs base {_baseWhiteness:0.000} = {num:+0.000;-0.000} over {pixels} pixel(s)"); return num.ToString("0.000", invariantCulture); } [TestHook("ComfortMagicBubbles.bubble.dimming")] private static string Dimming(string who, string effect) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) string problem; MeshRenderer val = BubbleTestHooks.FindSphere(who, effect, out problem); if ((Object)(object)val == (Object)null) { return problem; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return BubbleTestHooks.Reason("no main camera"); } if (_baseLuma < 0f) { return BubbleTestHooks.Reason("no base measured (call bubble.whiteness with mark \"base\" first)"); } if (!Measure(main, val, out var _, out var pixels, out var why, out var mean)) { return BubbleTestHooks.Reason(why); } float num = _baseLuma - Luma(mean); ModLog.Info($"BubbleLookTestHooks: luminance {Luma(mean):0.000} vs base {_baseLuma:0.000} = {num:+0.000;-0.000} darker over {pixels} pixel(s)"); return num.ToString("0.000", CultureInfo.InvariantCulture); } private static float Luma(Color c) { //IL_0005: 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_001e: Unknown result type (might be due to invalid IL or missing references) return 0.2126f * c.r + 0.7152f * c.g + 0.0722f * c.b; } [TestHook("ComfortMagicBubbles.bubble.meanColour")] private static string MeanColour(string who, string effect) { //IL_004d: 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_007b: Unknown result type (might be due to invalid IL or missing references) string problem; MeshRenderer val = BubbleTestHooks.FindSphere(who, effect, out problem); if ((Object)(object)val == (Object)null) { return problem; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return BubbleTestHooks.Reason("no main camera"); } if (!Measure(main, val, out var _, out var pixels, out var why, out var mean)) { return BubbleTestHooks.Reason(why); } string text = $"{Mathf.RoundToInt(mean.r * 255f)},{Mathf.RoundToInt(mean.g * 255f)},{Mathf.RoundToInt(mean.b * 255f)}"; ModLog.Info($"BubbleLookTestHooks: mean colour {text} over {pixels} pixel(s)"); return text; } [TestHook("ComfortMagicBubbles.bubble.forceMetallic")] private static string ForceMetallic(string who, string effect, double value) { string problem; MeshRenderer val = BubbleTestHooks.FindSphere(who, effect, out problem); if ((Object)(object)val == (Object)null) { return problem; } Material sharedMaterial = ((Renderer)val).sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null || !sharedMaterial.HasProperty("_Metallic")) { return BubbleTestHooks.Reason("sphere material has no _Metallic"); } sharedMaterial.SetFloat("_Metallic", (float)value); return "metallic " + sharedMaterial.GetFloat("_Metallic").ToString("0.00", CultureInfo.InvariantCulture); } [TestHook("ComfortMagicBubbles.bubble.setFloat")] private static string SetFloat(string who, string effect, string prop, double value) { string problem; MeshRenderer val = BubbleTestHooks.FindSphere(who, effect, out problem); if ((Object)(object)val == (Object)null) { return problem; } Material sharedMaterial = ((Renderer)val).sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null || !sharedMaterial.HasProperty(prop)) { return BubbleTestHooks.Reason("sphere material has no " + prop); } sharedMaterial.SetFloat(prop, (float)value); return prop + " = " + sharedMaterial.GetFloat(prop).ToString("0.000", CultureInfo.InvariantCulture); } [TestHook("ComfortMagicBubbles.bubble.keyword")] private static string Keyword(string who, string effect, string keyword, bool on) { //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) string problem; MeshRenderer val = BubbleTestHooks.FindSphere(who, effect, out problem); if ((Object)(object)val == (Object)null) { return problem; } Material sharedMaterial = ((Renderer)val).sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null) { return BubbleTestHooks.Reason("sphere has no material"); } if (!string.IsNullOrEmpty(keyword)) { if (on) { sharedMaterial.EnableKeyword(keyword); } else { sharedMaterial.DisableKeyword(keyword); } } LocalKeywordSpace keywordSpace = sharedMaterial.shader.keywordSpace; string text = string.Join(" ", ((LocalKeywordSpace)(ref keywordSpace)).keywordNames); string text2 = "known [" + text + "] on [" + string.Join(" ", sharedMaterial.shaderKeywords) + "]"; ModLog.Info("BubbleLookTestHooks: " + text2); return text2; } private static bool Measure(Camera camera, MeshRenderer sphere, out float whiteness, out int pixels, out string why, out Color mean) { //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_0046: 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_004f: 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_0059: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_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_0088: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) whiteness = 0f; pixels = 0; why = null; mean = Color.black; int num = 480; int num2 = Mathf.Max(1, Mathf.RoundToInt(480f * (float)Screen.height / (float)Mathf.Max(1, Screen.width))); Bounds bounds = ((Renderer)sphere).bounds; Vector3 val = camera.WorldToViewportPoint(((Bounds)(ref bounds)).center); Vector3 val2 = camera.WorldToViewportPoint(((Bounds)(ref bounds)).center + ((Component)camera).transform.right * ((Bounds)(ref bounds)).extents.x); if (val.z <= 0f) { why = "the bubble is behind the camera"; return false; } float num3 = val.x * (float)num; float num4 = val.y * (float)num2; float num5 = Mathf.Abs(val2.x - val.x) * (float)num * 0.9f; RenderTexture temporary = RenderTexture.GetTemporary(num, num2, 24, (RenderTextureFormat)0); RenderTexture targetTexture = camera.targetTexture; RenderTexture active = RenderTexture.active; Texture2D val3 = new Texture2D(num, num2, (TextureFormat)4, false); try { camera.targetTexture = temporary; camera.Render(); RenderTexture.active = temporary; val3.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0, false); val3.Apply(false); } finally { camera.targetTexture = targetTexture; RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } double num6 = 0.0; double num7 = 0.0; double num8 = 0.0; double num9 = 0.0; Color32[] pixels2 = val3.GetPixels32(); Object.Destroy((Object)(object)val3); for (int i = Mathf.Max(0, (int)(num4 - num5)); i < Mathf.Min(num2, (int)(num4 + num5) + 1); i++) { for (int j = Mathf.Max(0, (int)(num3 - num5)); j < Mathf.Min(num, (int)(num3 + num5) + 1); j++) { float num10 = (float)j - num3; float num11 = (float)i - num4; if (!(num10 * num10 + num11 * num11 > num5 * num5)) { Color32 val4 = pixels2[i * num + j]; num6 += (double)((float)Mathf.Min((int)val4.r, Mathf.Min((int)val4.g, (int)val4.b)) / 255f); num7 += (double)((float)(int)val4.r / 255f); num8 += (double)((float)(int)val4.g / 255f); num9 += (double)((float)(int)val4.b / 255f); pixels++; } } } if (pixels < 50) { why = $"only {pixels} pixel(s) of the bubble on screen (radius {num5:0.0} px)"; return false; } whiteness = (float)(num6 / (double)pixels); mean = new Color((float)(num7 / (double)pixels), (float)(num8 / (double)pixels), (float)(num9 / (double)pixels)); return true; } } internal static class BubbleProbe { internal const string NoEffect = "none"; internal const string NoSphere = "no sphere"; internal const string NoLight = "no light"; internal const string NoSmoke = "no smoke"; private const string SphereName = "Sphere"; private const float FullByte = 255f; private const float FullPercent = 100f; private static readonly int ColorId = Shader.PropertyToID("_Color"); private static readonly int PatternOpacityId = Shader.PropertyToID("_Opacity"); private static readonly FieldRef<StatusEffect, GameObject[]> Instances = AccessTools.FieldRefAccess<StatusEffect, GameObject[]>("m_startEffectInstances"); internal static MeshRenderer SphereOf(Character wearer, string effect, out string problem) { StatusEffect statusEffect = wearer.GetSEMan().GetStatusEffect(StringExtensionMethods.GetStableHashCode(effect)); GameObject[] array = (((Object)(object)statusEffect != (Object)null) ? Instances.Invoke(statusEffect) : null); MeshRenderer val = null; if (array != null) { GameObject[] array2 = array; foreach (GameObject bubble in array2) { val = (((Object)(object)val != (Object)null) ? val : SphereIn(bubble)); } } problem = (((Object)(object)val != (Object)null) ? null : (((Object)(object)statusEffect == (Object)null) ? "none" : "no sphere")); return val; } internal static MeshRenderer SphereIn(GameObject bubble) { Transform val = (((Object)(object)bubble != (Object)null) ? bubble.transform.Find("Sphere") : null); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<MeshRenderer>(); } internal static string LightOf(MeshRenderer sphere) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) Light val = (((Object)(object)sphere != (Object)null) ? ((Component)((Component)sphere).transform.parent).GetComponentInChildren<Light>(true) : null); if (!((Object)(object)val != (Object)null)) { return "no light"; } return $"{Hex(val.color)}/{Mathf.RoundToInt(BubbleLights.BaseIntensity(val) * 100f)}"; } internal static string SmokeOf(MeshRenderer sphere) { //IL_0058: 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_005d: 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) //IL_0078: Unknown result type (might be due to invalid IL or missing references) ParticleSystem val = null; ParticleSystem[] array = (ParticleSystem[])(((Object)(object)sphere != (Object)null) ? ((Array)((Component)((Component)sphere).transform.parent).GetComponentsInChildren<ParticleSystem>(false)) : ((Array)new ParticleSystem[0])); foreach (ParticleSystem val2 in array) { val = (((Object)(object)val != (Object)null) ? val : val2); } Color val3 = (((Object)(object)val != (Object)null) ? BubbleSmoke.StartColour(val) : Color.clear); if (!((Object)(object)val != (Object)null)) { return "no smoke"; } return $"{Hex(val3)}/{Mathf.RoundToInt(val3.a * 100f)}"; } private static string Hex(Color colour) { //IL_0005: 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_0031: Unknown result type (might be due to invalid IL or missing references) return $"#{Mathf.RoundToInt(colour.r * 255f):X2}{Mathf.RoundToInt(colour.g * 255f):X2}{Mathf.RoundToInt(colour.b * 255f):X2}"; } internal static string Look(MeshRenderer sphere) { //IL_003a: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) Material val = (((Object)(object)sphere != (Object)null) ? ((Renderer)sphere).sharedMaterial : null); int num; Color val2; if ((Object)(object)val != (Object)null) { num = (val.HasProperty(ColorId) ? 1 : 0); if (num != 0) { val2 = val.GetColor(ColorId); goto IL_003f; } } else { num = 0; } val2 = Color.clear; goto IL_003f; IL_003f: Color val3 = val2; if (num != 0 && val.HasProperty(PatternOpacityId)) { val3.a = val.GetFloat(PatternOpacityId); } if (num == 0) { return "no sphere"; } return $"{Hex(val3)}/{Mathf.RoundToInt(val3.a * 100f)}"; } } internal static class BubbleSituationTestHooks { private const float InteriorTestHeight = 5000f; private const float GroundClearance = 0.5f; [TestHook("ComfortMagicBubbles.bubble.indoors")] private static string Indoors(bool inside) { //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_002b: 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_007d: 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) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return BubbleTestHooks.Reason("no local player"); } Vector3 position = ((Component)localPlayer).transform.pos