using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Ostranauts.Core;
using Ostranauts.UI.CrewBar;
using Ostranauts.UI.Loading;
using Ostranauts.UI.MegaToolTip;
using OstranautsSidebar.Core;
using OstranautsSidebar.Data;
using OstranautsSidebar.UI;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[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 OstranautsSidebar
{
[BepInPlugin("com.ostranauts.sidebar", "Character Sidebar", "0.3.0")]
public class Plugin : BaseUnityPlugin
{
internal sealed class ConfigurationManagerAttributes
{
public bool? Browsable;
}
internal static ManualLogSource Log = null;
internal static Plugin Instance = null;
internal static ConfigEntry<float> PanelWidth = null;
internal static ConfigEntry<float> BottomOffset = null;
internal static ConfigEntry<float> ReferenceHeight = null;
internal static ConfigEntry<bool> StartVisible = null;
internal static ConfigEntry<bool> HideWithHelmet = null;
internal static ConfigEntry<bool> MinimiseWithHelmet = null;
private static readonly ConfigurationManagerAttributes Hidden = new ConfigurationManagerAttributes
{
Browsable = false
};
private void Awake()
{
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Expected O, but got Unknown
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Expected O, but got Unknown
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
ModLog.Log = ((BaseUnityPlugin)this).Logger;
PanelWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "PanelWidth", 195f, new ConfigDescription("Sidebar width, in 1080p-reference pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(120f, 400f), Array.Empty<object>()));
BottomOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "BottomOffset", 88f, new ConfigDescription("Fallback bottom gap (reference pixels) used only if the vanilla HUD bar can't be measured. Normally the panel pins itself to the actual bar height.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>()));
ReferenceHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Layout", "ReferenceHeight", 720f, new ConfigDescription("Canvas reference height. Lower = larger UI/fonts; raise if the panel feels too big. Applies on next game load.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(480f, 1440f), Array.Empty<object>()));
StartVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour", "StartVisible", true, "Whether the panel is shown when a game loads (toggle anytime with the side tab).");
HideWithHelmet = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour", "HideWithHelmet", false, "Hide the sidebar completely — panel and side tab both — while the pressure-suit/EVA helmet overlay is on screen. Off by default; MinimiseWithHelmet is usually what you want instead, since it leaves the tab behind.");
bool available = HelmetLinkClient.Available;
MinimiseWithHelmet = ((BaseUnityPlugin)this).Config.Bind<bool>("Behaviour", "MinimiseWithHelmet", available, "Fold the panel away to its side tab whenever the helmet is up, and unfold it when the helmet comes off. This is about immersion rather than screen space: you're looking through a visor, and a panel floating over the glass breaks that. It folds even when the visor is dark, since a suit with flat cells is a moment to feel rather than a reason for a panel. The side tab stays put, so you can always pull your status back up. Defaults on when the Helmet HUD mod is detected (the two are designed to work together), off otherwise — safe to flip either way.");
Log.LogInfo((object)"Character Sidebar v0.3.0 loading...");
GameObject val = new GameObject("OstranautsSidebarController");
val.AddComponent<SidebarController>();
Object.DontDestroyOnLoad((Object)val);
Log.LogInfo((object)"SidebarController bootstrapped.");
}
internal static ConfigEntry<bool> BindExpanded(string key, bool defaultExpanded)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
return ((BaseUnityPlugin)Instance).Config.Bind<bool>("SectionsExpanded", key, defaultExpanded, new ConfigDescription("Whether the " + key + " section is expanded. Updated automatically when you click its header in-game.", (AcceptableValueBase)null, new object[1] { Hidden }));
}
private void OnDestroy()
{
SidebarController.Instance?.Destroy();
}
}
internal static class PluginInfo
{
public const string GUID = "com.ostranauts.sidebar";
public const string NAME = "Character Sidebar";
public const string VERSION = "0.3.0";
}
}
namespace OstranautsSidebar.UI
{
public class RowTooltip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
public string Title = string.Empty;
public string Body = string.Empty;
public void OnPointerEnter(PointerEventData eventData)
{
if (!string.IsNullOrEmpty(Title) || !string.IsNullOrEmpty(Body))
{
SidebarTooltip.Instance?.Show(Title, Body);
}
}
public void OnPointerExit(PointerEventData eventData)
{
SidebarTooltip.Instance?.Hide();
}
}
public class SidebarPanel : MonoBehaviour
{
private sealed class Section
{
public GameObject Root;
public GameObject ContentObj;
public Text Arrow;
public ConfigEntry<bool> State;
public Transform Content => ContentObj.transform;
public bool Expanded => ContentObj.activeSelf;
public void SetExpanded(bool on)
{
ContentObj.SetActive(on);
Arrow.text = (on ? "▾" : "▸");
State.Value = on;
}
}
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static UnityAction <>9__42_0;
internal void <BuildToggleTab>b__42_0()
{
SidebarController.Instance?.ToggleVisibility();
}
}
private static readonly Color BgColor = Hex("#121218");
private static readonly Color HeaderBgColor = Hex("#14141e");
private static readonly Color SectionBgColor = Hex("#141420");
private static readonly Color BorderColor = Hex("#1e1e2e");
private static readonly Color TextDefault = Hex("#b0a898");
private static readonly Color TextDim = Hex("#505068");
private static readonly Color TextHeader = Hex("#d0c8b8");
private static readonly Color TextSectionTitle = Hex("#505070");
private static readonly Color SubSectionBgColor = Hex("#10101a");
private static readonly Color SubSectionTitle = Hex("#42425a");
private static readonly Color SkillLearnedText = Hex("#b0a898");
private static readonly Color SkillTrainingText = Hex("#505068");
private static readonly Color TraitPosBg = Hex("#121e12");
private static readonly Color TraitPosBorder = Hex("#1e2e1e");
private static readonly Color TraitPosText = Hex("#4a7a4a");
private static readonly Color TraitNegBg = Hex("#1e1212");
private static readonly Color TraitNegBorder = Hex("#2e1e1e");
private static readonly Color TraitNegText = Hex("#7a4a4a");
private static readonly Color TraitNeuText = Hex("#505070");
private static readonly Color DotWarning = Hex("#c89430");
private static readonly Color DotCritical = Hex("#c03030");
private static readonly Color CondWarningText = Hex("#b08a48");
private static readonly Color CondCriticalText = Hex("#c85858");
private static readonly Color AliveDot = Hex("#3aaa5a");
private static readonly Color FooterText = Hex("#252535");
private Transform? _skillsContent;
private Transform? _skillTrainingContent;
private GameObject? _skillTrainingSection;
private Transform? _traitTrainingContent;
private GameObject? _traitTrainingSection;
private Transform? _traitsContent;
private Transform? _conditionsContent;
private GameObject? _conditionsSection;
private GameObject? _canvasRoot;
private Canvas? _canvas;
private RectTransform? _rt;
private RectTransform? _tabRect;
private Text? _tabLabel;
private static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];
private float _heightFraction = 1f;
private float? _topOffsetOverride;
private bool _geometryApplied;
private float _lastGeomTime;
private string _sigSkills = "";
private string _sigTrainSkills = "";
private string _sigTraits = "";
private string _sigTrainTraits = "";
private string _sigConds = "";
private bool _lastVisible = true;
private bool _lastShowTab = true;
private bool _visInit;
private static Sprite? _gridSprite;
private static Sprite? _gradientSprite;
private static Sprite? _fadeSprite;
public Canvas? Canvas => _canvas;
public static SidebarPanel Create()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
GameObject val = CreateOwnCanvas();
GameObject val2 = new GameObject("OstranautsSidebarPanel");
val2.transform.SetParent(val.transform, false);
SidebarPanel sidebarPanel = val2.AddComponent<SidebarPanel>();
sidebarPanel._canvasRoot = val;
sidebarPanel.Build(val.GetComponent<Canvas>());
sidebarPanel.BuildToggleTab(val.transform);
SidebarTooltip.Create(val.transform);
return sidebarPanel;
}
private void BuildToggleTab(Transform canvas)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
GameObject val = new GameObject("OstranautsSidebarTab");
val.transform.SetParent(canvas, false);
_tabRect = val.AddComponent<RectTransform>();
_tabRect.anchorMin = new Vector2(1f, 0f);
_tabRect.anchorMax = new Vector2(1f, 0f);
_tabRect.pivot = new Vector2(1f, 0.5f);
_tabRect.sizeDelta = new Vector2(16f, 64f);
_tabRect.anchoredPosition = new Vector2(0f - Plugin.PanelWidth.Value, 0f);
AddImage(val, HeaderBgColor);
ButtonClickedEvent onClick = val.AddComponent<Button>().onClick;
object obj = <>c.<>9__42_0;
if (obj == null)
{
UnityAction val2 = delegate
{
SidebarController.Instance?.ToggleVisibility();
};
<>c.<>9__42_0 = val2;
obj = (object)val2;
}
((UnityEvent)onClick).AddListener((UnityAction)obj);
GameObject val3 = MakeRect("TabLabel", val.transform);
RectTransform component = val3.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
_tabLabel = AddText(val3, "◀\nS\nT\nA\nT\nS", 9, TextSectionTitle, (FontStyle)0);
_tabLabel.alignment = (TextAnchor)4;
}
public void SetHeightFraction(float frac)
{
frac = Mathf.Clamp(frac, 0.1f, 1f);
if (_topOffsetOverride.HasValue || !Mathf.Approximately(frac, _heightFraction) || !_geometryApplied || !(Time.unscaledTime - _lastGeomTime < 1f))
{
_heightFraction = frac;
_topOffsetOverride = null;
ApplyGeometry();
}
}
public void SetTopBelowScreenY(float screenY)
{
float num = (((Object)(object)_canvas != (Object)null && _canvas.scaleFactor > 0f) ? _canvas.scaleFactor : 1f);
float num2 = ((float)Screen.height - screenY) / num + 8f;
if (!_topOffsetOverride.HasValue || !(Mathf.Abs(_topOffsetOverride.Value - num2) < 4f))
{
_topOffsetOverride = num2;
ApplyGeometry();
}
}
public void ApplyGeometry()
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: 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)
if ((Object)(object)_rt == (Object)null)
{
return;
}
_geometryApplied = true;
_lastGeomTime = Time.unscaledTime;
float num = Plugin.BottomOffset.Value;
RectTransform val = TryGetCrewBarRect();
if ((Object)(object)val != (Object)null && (Object)(object)_canvas != (Object)null)
{
val.GetWorldCorners(_corners);
Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
Vector2 val2 = RectTransformUtility.WorldToScreenPoint(((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null, _corners[1]);
float scaleFactor = _canvas.scaleFactor;
if (scaleFactor > 0f)
{
num = val2.y / scaleFactor;
}
}
float num2 = (((Object)(object)_canvas != (Object)null && _canvas.scaleFactor > 0f) ? ((float)Screen.height / _canvas.scaleFactor) : ((float)Screen.height));
float num3 = Mathf.Max(0f, num2 - num);
float num4 = _topOffsetOverride ?? (num3 * (1f - _heightFraction));
num4 = Mathf.Clamp(num4, 0f, Mathf.Max(0f, num3 - 40f));
float value = Plugin.PanelWidth.Value;
_rt.offsetMin = new Vector2(0f - value, num);
_rt.offsetMax = new Vector2(0f, 0f - num4);
if ((Object)(object)_tabRect != (Object)null)
{
_tabRect.anchoredPosition = new Vector2(_tabRect.anchoredPosition.x, num + num3 / 6f);
}
}
private static RectTransform? TryGetCrewBarRect()
{
try
{
GUICrewStatus instance = MonoSingleton<GUICrewStatus>.Instance;
return ((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponent<RectTransform>() : null;
}
catch (Exception)
{
return null;
}
}
private void OnDestroy()
{
if ((Object)(object)_canvasRoot != (Object)null)
{
Object.Destroy((Object)(object)_canvasRoot);
}
}
private void Build(Canvas rootCanvas)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: 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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
_canvas = rootCanvas;
float value = Plugin.PanelWidth.Value;
_rt = ((Component)this).gameObject.AddComponent<RectTransform>();
_rt.anchorMin = new Vector2(1f, 0f);
_rt.anchorMax = new Vector2(1f, 1f);
_rt.pivot = new Vector2(1f, 1f);
_rt.offsetMin = new Vector2(0f - value, Plugin.BottomOffset.Value);
_rt.offsetMax = new Vector2(0f, 0f);
AddImage(((Component)this).gameObject, BgColor);
AddBackgroundDecor(((Component)this).gameObject);
BuildScrollArea();
BuildFooter();
ApplyGeometry();
}
private void BuildScrollArea()
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
GameObject val = MakeRect("ScrollArea", ((Component)this).gameObject.transform);
RectTransform component = val.GetComponent<RectTransform>();
component.anchorMin = new Vector2(0f, 0f);
component.anchorMax = new Vector2(1f, 1f);
component.offsetMin = new Vector2(0f, 20f);
component.offsetMax = new Vector2(0f, -4f);
ScrollRect obj = val.AddComponent<ScrollRect>();
obj.horizontal = false;
obj.vertical = true;
obj.scrollSensitivity = 24f;
obj.movementType = (MovementType)2;
obj.viewport = component;
val.AddComponent<RectMask2D>();
GameObject val2 = MakeRect("Content", val.transform);
RectTransform component2 = val2.GetComponent<RectTransform>();
component2.anchorMin = new Vector2(0f, 1f);
component2.anchorMax = new Vector2(1f, 1f);
component2.pivot = new Vector2(0.5f, 1f);
component2.sizeDelta = new Vector2(0f, 0f);
VerticalLayoutGroup obj2 = val2.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 0f;
val2.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
obj.content = val2.GetComponent<RectTransform>();
Section section = BuildCollapsible(val2.transform, "TRAITS", "TraitsGroup", defaultExpanded: true);
Section section2 = BuildCollapsible(section.Content, "ESTABLISHED", "TraitsEstablished", defaultExpanded: false, sub: true);
Section section3 = BuildCollapsible(section.Content, "TRAINING", "TraitsTraining", defaultExpanded: true, sub: true);
_traitsContent = section2.Content;
_traitTrainingSection = section3.Root;
_traitTrainingContent = section3.Content;
Section section4 = BuildCollapsible(val2.transform, "SKILLS", "SkillsGroup", defaultExpanded: true);
Section section5 = BuildCollapsible(section4.Content, "LEARNED", "SkillsLearned", defaultExpanded: false, sub: true);
Section section6 = BuildCollapsible(section4.Content, "TRAINING", "SkillsTraining", defaultExpanded: true, sub: true);
_skillsContent = section5.Content;
_skillTrainingSection = section6.Root;
_skillTrainingContent = section6.Content;
Section section7 = BuildCollapsible(val2.transform, "STATUS", "Status", defaultExpanded: true);
_conditionsSection = section7.Root;
_conditionsContent = section7.Content;
}
private void BuildFooter()
{
//IL_0027: 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_0051: 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_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: 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_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
GameObject val = MakeRect("Footer", ((Component)this).gameObject.transform);
RectTransform component = val.GetComponent<RectTransform>();
component.anchorMin = new Vector2(0f, 0f);
component.anchorMax = new Vector2(1f, 0f);
component.pivot = new Vector2(0.5f, 0f);
component.sizeDelta = new Vector2(0f, 20f);
AddImage(val, HeaderBgColor);
GameObject obj = MakeRect("FooterLabel", val.transform);
RectTransform component2 = obj.GetComponent<RectTransform>();
component2.anchorMin = new Vector2(0f, 0f);
component2.anchorMax = new Vector2(1f, 1f);
component2.offsetMin = new Vector2(10f, 0f);
component2.offsetMax = new Vector2(-10f, 0f);
AddText(obj, "CharSidebar v0.3.0", 9, FooterText, (FontStyle)0);
}
private Section BuildCollapsible(Transform parent, string title, string persistKey, bool defaultExpanded, bool sub = false)
{
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_017c: 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_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0205: Expected O, but got Unknown
//IL_0268: Unknown result type (might be due to invalid IL or missing references)
//IL_0272: Expected O, but got Unknown
ConfigEntry<bool> val = Plugin.BindExpanded(persistKey, defaultExpanded);
GameObject val2 = MakeRect("Section_" + persistKey, parent);
VerticalLayoutGroup obj = val2.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
((HorizontalOrVerticalLayoutGroup)obj).spacing = 0f;
val2.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
GameObject val3 = MakeRect("SectionHeader", val2.transform);
AddLayoutElement(val3, -1f, sub ? 20f : 22f);
AddImage(val3, sub ? SubSectionBgColor : SectionBgColor);
GameObject obj2 = MakeRect("Title", val3.transform);
RectTransform component = obj2.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = new Vector2((float)(sub ? 20 : 10), 0f);
component.offsetMax = new Vector2(-22f, 0f);
AddText(obj2, title, 9, sub ? SubSectionTitle : TextSectionTitle, (FontStyle)0);
GameObject obj3 = MakeRect("Arrow", val3.transform);
RectTransform component2 = obj3.GetComponent<RectTransform>();
component2.anchorMin = new Vector2(1f, 0f);
component2.anchorMax = new Vector2(1f, 1f);
component2.pivot = new Vector2(1f, 0.5f);
component2.sizeDelta = new Vector2(18f, 0f);
component2.anchoredPosition = new Vector2(-6f, 0f);
Text val4 = AddText(obj3, "▾", 9, sub ? SubSectionTitle : TextSectionTitle, (FontStyle)0);
val4.alignment = (TextAnchor)4;
GameObject val5 = MakeRect("SectionContent", val2.transform);
VerticalLayoutGroup obj4 = val5.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj4).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj4).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandWidth = true;
((HorizontalOrVerticalLayoutGroup)obj4).childForceExpandHeight = false;
((LayoutGroup)obj4).padding = new RectOffset(0, 0, 3, 3);
((HorizontalOrVerticalLayoutGroup)obj4).spacing = 0f;
val5.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
Section section = new Section
{
Root = val2,
ContentObj = val5,
Arrow = val4,
State = val
};
section.SetExpanded(val.Value);
((UnityEvent)val3.AddComponent<Button>().onClick).AddListener((UnityAction)delegate
{
section.SetExpanded(!section.Expanded);
});
return section;
}
public void Populate(CharacterSnapshot data)
{
string sigSkills;
if ((sigSkills = SkillSig(data.Skills)) != _sigSkills)
{
_sigSkills = sigSkills;
PopulateSkillRows(_skillsContent, data.Skills);
}
if ((sigSkills = SkillSig(data.TrainingSkills)) != _sigTrainSkills)
{
_sigTrainSkills = sigSkills;
PopulateTrainingSection(_skillTrainingSection, _skillTrainingContent, data.TrainingSkills);
}
if ((sigSkills = TraitSig(data.Traits)) != _sigTraits)
{
_sigTraits = sigSkills;
PopulateTraits(data.Traits);
}
if ((sigSkills = SkillSig(data.TrainingTraits)) != _sigTrainTraits)
{
_sigTrainTraits = sigSkills;
PopulateTrainingSection(_traitTrainingSection, _traitTrainingContent, data.TrainingTraits);
}
if ((sigSkills = CondSig(data.ActiveConditions)) != _sigConds)
{
_sigConds = sigSkills;
PopulateConditions(data.ActiveConditions);
}
}
private static string SkillSig(List<SkillEntry> list)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (SkillEntry item in list)
{
stringBuilder.Append(item.Name).Append(item.Learned ? '✓' : '◌').Append(item.TrainingPercent)
.Append('|');
}
return stringBuilder.ToString();
}
private static string TraitSig(List<TraitEntry> list)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (TraitEntry item in list)
{
stringBuilder.Append(item.Name).Append((int)item.Polarity).Append('|');
}
return stringBuilder.ToString();
}
private static string CondSig(List<ConditionEntry> list)
{
StringBuilder stringBuilder = new StringBuilder();
foreach (ConditionEntry item in list)
{
stringBuilder.Append(item.Name).Append((int)item.Tone).Append((int)item.Trend)
.Append('|');
}
return stringBuilder.ToString();
}
private void PopulateTrainingSection(GameObject? section, Transform? content, List<SkillEntry> rows)
{
if ((Object)(object)section != (Object)null)
{
section.SetActive(rows.Count > 0);
}
PopulateSkillRows(content, rows);
}
private void PopulateSkillRows(Transform? content, List<SkillEntry> skills)
{
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Expected O, but got Unknown
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)content == (Object)null)
{
return;
}
ClearChildren(content);
foreach (SkillEntry skill in skills)
{
GameObject val = MakeRect("SkillRow", content);
AddLayoutElement(val, -1f, 22f);
HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)obj).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
((LayoutGroup)obj).padding = new RectOffset(12, 10, 0, 0);
((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
GameObject go = MakeRect("Name", val.transform);
AddLayoutElement(go, -1f, -1f, 1f);
AddText(go, skill.Name, 11, SkillLearnedText, (FontStyle)0);
string title = skill.Name;
if (!skill.Learned)
{
GameObject go2 = MakeRect("Pct", val.transform);
AddLayoutElement(go2, 34f, -1f, 0f);
AddText(go2, skill.TrainingPercent + "%", 11, SkillTrainingText, (FontStyle)0).alignment = (TextAnchor)5;
title = $"{skill.Name} ({skill.TrainingPercent}%)";
}
AddRowTooltip(val, title, skill.Description);
}
}
private void PopulateTraits(List<TraitEntry> traits)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: 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_003f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_traitsContent == (Object)null)
{
return;
}
ClearChildren(_traitsContent);
foreach (TraitEntry trait in traits)
{
Color color = ((trait.Polarity == TraitPolarity.Positive) ? TraitPosText : ((trait.Polarity == TraitPolarity.Negative) ? TraitNegText : TraitNeuText));
GameObject val = MakeRect("TraitRow", _traitsContent);
AddLayoutElement(val, -1f, 22f);
HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)obj).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
((LayoutGroup)obj).padding = new RectOffset(12, 10, 0, 0);
((HorizontalOrVerticalLayoutGroup)obj).spacing = 7f;
GameObject go = MakeRect("Dot", val.transform);
AddLayoutElement(go, 6f, 6f, 0f);
((Graphic)AddImage(go, color)).raycastTarget = false;
GameObject go2 = MakeRect("Name", val.transform);
AddLayoutElement(go2, -1f, -1f, 1f);
AddText(go2, trait.Name, 11, color, (FontStyle)0);
AddRowTooltip(val, trait.Name, trait.Description);
}
}
private void PopulateConditions(List<ConditionEntry> conditions)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Expected O, but got Unknown
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_015e: Unknown result type (might be due to invalid IL or missing references)
//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_conditionsContent == (Object)null || (Object)(object)_conditionsSection == (Object)null)
{
return;
}
ClearChildren(_conditionsContent);
_conditionsSection.SetActive(conditions.Count > 0);
foreach (ConditionEntry condition in conditions)
{
Color color = ToneDot(condition.Tone);
Color color2 = ToneText(condition.Tone);
GameObject val = MakeRect("CondRow", _conditionsContent);
AddLayoutElement(val, -1f, 22f);
HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>();
((LayoutGroup)obj).childAlignment = (TextAnchor)3;
((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
((LayoutGroup)obj).padding = new RectOffset(12, 10, 0, 0);
((HorizontalOrVerticalLayoutGroup)obj).spacing = 7f;
bool flag = condition.Tone == ConditionTone.Critical;
float num = (flag ? 8f : 6f);
GameObject go = MakeRect("Dot", val.transform);
AddLayoutElement(go, num, num, 0f);
((Graphic)AddImage(go, color)).raycastTarget = false;
GameObject go2 = MakeRect("Label", val.transform);
AddLayoutElement(go2, -1f, -1f, 1f);
AddText(go2, condition.Name, 11, color2, (FontStyle)(flag ? 1 : 0));
if (condition.Trend != TrendDirection.None)
{
GameObject go3 = MakeRect("Trend", val.transform);
AddLayoutElement(go3, 14f, -1f, 0f);
AddText(go3, (condition.Trend == TrendDirection.Up) ? "↗" : "↘", 14, color2, (FontStyle)1).alignment = (TextAnchor)4;
}
AddRowTooltip(val, condition.Name, condition.Description);
}
}
private static Color ToneDot(ConditionTone tone)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//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_0028: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
return (Color)(tone switch
{
ConditionTone.Good => AliveDot,
ConditionTone.Critical => DotCritical,
ConditionTone.Warning => DotWarning,
_ => TextDim,
});
}
private static Color ToneText(ConditionTone tone)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//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_0028: 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_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_0036: Unknown result type (might be due to invalid IL or missing references)
return (Color)(tone switch
{
ConditionTone.Good => TraitPosText,
ConditionTone.Critical => CondCriticalText,
ConditionTone.Warning => CondWarningText,
_ => TextDefault,
});
}
public void SetVisible(bool visible, bool showTab = true)
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
if (!_visInit || visible != _lastVisible || showTab != _lastShowTab)
{
_visInit = true;
_lastVisible = visible;
_lastShowTab = showTab;
((Component)this).gameObject.SetActive(visible);
if ((Object)(object)_tabRect != (Object)null)
{
((Component)_tabRect).gameObject.SetActive(showTab);
_tabRect.anchoredPosition = new Vector2(visible ? (0f - Plugin.PanelWidth.Value) : 0f, _tabRect.anchoredPosition.y);
}
if ((Object)(object)_tabLabel != (Object)null)
{
_tabLabel.text = (visible ? "◀\nS\nT\nA\nT\nS" : "▶\nS\nT\nA\nT\nS");
}
}
}
private static GameObject MakeRect(string name, Transform parent)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
GameObject val = new GameObject(name);
val.transform.SetParent(parent, false);
val.AddComponent<RectTransform>();
return val;
}
private static Image AddImage(GameObject go, Color color)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
Image obj = go.AddComponent<Image>();
((Graphic)obj).color = color;
return obj;
}
private static Text AddText(GameObject go, string content, int size, Color color, FontStyle style = (FontStyle)0)
{
//IL_0015: 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)
Text obj = go.AddComponent<Text>();
obj.text = content;
obj.fontSize = size;
((Graphic)obj).color = color;
obj.fontStyle = style;
obj.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
obj.alignment = (TextAnchor)3;
obj.horizontalOverflow = (HorizontalWrapMode)1;
obj.verticalOverflow = (VerticalWrapMode)1;
((Graphic)obj).raycastTarget = false;
return obj;
}
private static void AddRowTooltip(GameObject row, string title, string body)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
if (!string.IsNullOrEmpty(body))
{
((Graphic)row.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
RowTooltip rowTooltip = row.AddComponent<RowTooltip>();
rowTooltip.Title = title;
rowTooltip.Body = body;
}
}
private void AddBackgroundDecor(GameObject panel)
{
Image obj = MakeFullStretchChild("BgGradient", panel.transform).AddComponent<Image>();
obj.sprite = _gradientSprite ?? (_gradientSprite = MakeGradientSprite());
obj.type = (Type)0;
((Graphic)obj).raycastTarget = false;
Image obj2 = MakeFullStretchChild("BgGrid", panel.transform).AddComponent<Image>();
obj2.sprite = _gridSprite ?? (_gridSprite = MakeGridSprite());
obj2.type = (Type)2;
((Graphic)obj2).raycastTarget = false;
Image obj3 = MakeFullStretchChild("BgGridFade", panel.transform).AddComponent<Image>();
obj3.sprite = _fadeSprite ?? (_fadeSprite = MakeLeftFadeSprite());
obj3.type = (Type)0;
((Graphic)obj3).raycastTarget = false;
}
private static GameObject MakeFullStretchChild(string name, Transform parent)
{
//IL_000e: 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_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = MakeRect(name, parent);
RectTransform component = obj.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
return obj;
}
private static Sprite MakeGridSprite()
{
//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_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_0063: 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_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(26, 26, (TextureFormat)4, false)
{
filterMode = (FilterMode)0,
wrapMode = (TextureWrapMode)0
};
Color val2 = default(Color);
((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
Color val3 = default(Color);
((Color)(ref val3))..ctor(0.32f, 0.32f, 0.46f, 0.16f);
Color[] array = (Color[])(object)new Color[676];
for (int i = 0; i < array.Length; i++)
{
array[i] = val2;
}
for (int j = 0; j < 26; j++)
{
array[j] = val3;
}
for (int k = 0; k < 26; k++)
{
array[k * 26] = val3;
}
val.SetPixels(array);
val.Apply();
return Sprite.Create(val, new Rect(0f, 0f, 26f, 26f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
}
private static Sprite MakeLeftFadeSprite()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
Texture2D val = new Texture2D(64, 1, (TextureFormat)4, false)
{
filterMode = (FilterMode)1,
wrapMode = (TextureWrapMode)1
};
Color[] array = (Color[])(object)new Color[64];
for (int i = 0; i < 64; i++)
{
float num = (float)i / 63f;
float num2 = Mathf.Clamp01((1f - num) * 1.8f);
array[i] = new Color(BgColor.r, BgColor.g, BgColor.b, num2);
}
val.SetPixels(array);
val.Apply();
return Sprite.Create(val, new Rect(0f, 0f, 64f, 1f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
}
private static Sprite MakeGradientSprite()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//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_007b: 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)
Texture2D val = new Texture2D(1, 64, (TextureFormat)4, false)
{
filterMode = (FilterMode)1,
wrapMode = (TextureWrapMode)1
};
Color[] array = (Color[])(object)new Color[64];
for (int i = 0; i < 64; i++)
{
float num = (float)i / 63f;
array[i] = new Color(0.4f, 0.4f, 0.55f, 0.06f * num);
}
val.SetPixels(array);
val.Apply();
return Sprite.Create(val, new Rect(0f, 0f, 1f, 64f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0);
}
private static LayoutElement AddLayoutElement(GameObject go, float preferredWidth = -1f, float preferredHeight = -1f, float flexWidth = -1f, float flexHeight = -1f)
{
LayoutElement val = go.AddComponent<LayoutElement>();
if (preferredWidth >= 0f)
{
val.preferredWidth = preferredWidth;
}
if (preferredHeight >= 0f)
{
val.preferredHeight = preferredHeight;
}
if (flexWidth >= 0f)
{
val.flexibleWidth = flexWidth;
}
if (flexHeight >= 0f)
{
val.flexibleHeight = flexHeight;
}
return val;
}
private static void ClearChildren(Transform parent)
{
for (int num = parent.childCount - 1; num >= 0; num--)
{
Object.Destroy((Object)(object)((Component)parent.GetChild(num)).gameObject);
}
}
private static Color Hex(string hex)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
Color result = default(Color);
ColorUtility.TryParseHtmlString(hex, ref result);
return result;
}
private static GameObject CreateOwnCanvas()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: 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_0066: Expected O, but got Unknown
//IL_0067: Expected O, but got Unknown
GameObject val = new GameObject("OstranautsSidebarCanvas");
Canvas obj = val.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 5000;
CanvasScaler obj2 = val.AddComponent<CanvasScaler>();
obj2.uiScaleMode = (ScaleMode)1;
obj2.referenceResolution = new Vector2(1920f, Plugin.ReferenceHeight.Value);
obj2.screenMatchMode = (ScreenMatchMode)0;
obj2.matchWidthOrHeight = 1f;
val.AddComponent<GraphicRaycaster>();
Object.DontDestroyOnLoad((Object)val);
return val;
}
}
public class SidebarTooltip : MonoBehaviour
{
private RectTransform _canvasRect;
private RectTransform _rt;
private Text _title;
private Text _body;
private bool _shown;
private static readonly Color BgColor = Hex("#0c0c12");
private static readonly Color TitleColor = Hex("#d0c8b8");
private static readonly Color BodyColor = Hex("#9a9286");
private const float Width = 240f;
public static SidebarTooltip? Instance { get; private set; }
public static SidebarTooltip Create(Transform canvas)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("OstranautsSidebarTooltip");
val.transform.SetParent(canvas, false);
SidebarTooltip sidebarTooltip = val.AddComponent<SidebarTooltip>();
sidebarTooltip.Build((RectTransform?)(object)((canvas is RectTransform) ? canvas : null));
return sidebarTooltip;
}
private void Awake()
{
Instance = this;
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
private void Build(RectTransform? canvasRect)
{
//IL_0035: 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_0051: 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_0081: 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_00c7: Expected O, but got Unknown
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
_canvasRect = canvasRect;
_rt = ((Component)this).gameObject.AddComponent<RectTransform>();
RectTransform rt = _rt;
RectTransform rt2 = _rt;
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(0f, 0f);
rt2.anchorMax = val;
rt.anchorMin = val;
_rt.pivot = new Vector2(1f, 1f);
_rt.sizeDelta = new Vector2(240f, 0f);
Image obj = ((Component)this).gameObject.AddComponent<Image>();
((Graphic)obj).color = BgColor;
((Graphic)obj).raycastTarget = false;
VerticalLayoutGroup obj2 = ((Component)this).gameObject.AddComponent<VerticalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
((LayoutGroup)obj2).padding = new RectOffset(8, 8, 6, 6);
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 3f;
((Component)this).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
_title = MakeText("Title", 12, TitleColor, (FontStyle)1);
_body = MakeText("Body", 11, BodyColor, (FontStyle)0);
((Component)this).gameObject.SetActive(false);
}
private Text MakeText(string name, int size, Color color, FontStyle style)
{
//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_0018: 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_0043: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
val.transform.SetParent(((Component)this).transform, false);
val.AddComponent<RectTransform>();
Text obj = val.AddComponent<Text>();
obj.font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
obj.fontSize = size;
((Graphic)obj).color = color;
obj.fontStyle = style;
obj.alignment = (TextAnchor)0;
obj.horizontalOverflow = (HorizontalWrapMode)0;
obj.verticalOverflow = (VerticalWrapMode)1;
((Graphic)obj).raycastTarget = false;
return obj;
}
public void Show(string title, string body)
{
_title.text = title ?? string.Empty;
_body.text = body ?? string.Empty;
((Component)_body).gameObject.SetActive(!string.IsNullOrEmpty(body));
_shown = true;
((Component)this).transform.SetAsLastSibling();
((Component)this).gameObject.SetActive(true);
Reposition();
}
public void Hide()
{
_shown = false;
((Component)this).gameObject.SetActive(false);
}
private void LateUpdate()
{
if (_shown)
{
Reposition();
}
}
private void Reposition()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_canvasRect == (Object)null)
{
return;
}
Vector2 val = Vector2.op_Implicit(Input.mousePosition);
Vector2 val2 = default(Vector2);
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasRect, val, (Camera)null, ref val2))
{
Rect rect = _canvasRect.rect;
float num = val2.x - ((Rect)(ref rect)).xMin - 8f;
float num2 = val2.y - ((Rect)(ref rect)).yMin + 8f;
Rect rect2 = _rt.rect;
float width = ((Rect)(ref rect2)).width;
rect2 = _rt.rect;
float height = ((Rect)(ref rect2)).height;
if (num < width)
{
num = width;
}
if (num > ((Rect)(ref rect)).width)
{
num = ((Rect)(ref rect)).width;
}
if (num2 > ((Rect)(ref rect)).height)
{
num2 = ((Rect)(ref rect)).height;
}
if (num2 < height)
{
num2 = height;
}
_rt.anchoredPosition = new Vector2(num, num2);
}
}
private static Color Hex(string hex)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
Color result = default(Color);
ColorUtility.TryParseHtmlString(hex, ref result);
return result;
}
}
}
namespace OstranautsSidebar.Data
{
internal static class CharacterDataReader
{
private const int DISPLAY_NEVER = 0;
private static readonly HashSet<string> TraitNames = new HashSet<string>(StringComparer.Ordinal)
{
"IsAgliophobic", "IsAmbitious", "IsApathetic", "IsArrogant", "IsBeautiful", "IsBrave", "IsCharismatic", "IsChaste", "IsClumsy", "IsComedian",
"IsComplacent", "IsCoordinated", "IsCraven", "IsCruel", "IsDiligent", "IsFeeble", "IsFinicky", "IsFit", "IsFollower", "IsForgiving",
"IsFragile", "IsGenius", "IsGlutton", "IsGregarious", "IsHealerFast", "IsHealerSlow", "IsHonest", "IsHumble", "IsHumorless", "IsHypovolemic2",
"IsImmunoSuppressed", "IsImpatient", "IsInsomniac", "IsIronStomach", "IsKind", "IsLeader", "IsLiar", "IsLoyal", "IsLustful", "IsMasochist",
"IsMetabFast", "IsMetabSlow", "IsOblivious", "IsObservant", "IsObtuse", "IsOptimist", "IsPatient", "IsPessimist", "IsPoorHearing", "IsPushover",
"IsQuitter", "IsRepulsive", "IsSelfish", "IsSelfless", "IsSharpHearing", "IsShy", "IsSleeperHeavy", "IsSleeperLight", "IsSlovenly", "IsSmoker",
"IsStrong", "IsStubborn", "IsSuspicious", "IsTemperate", "IsTidy", "IsTough", "IsTreacherous", "IsTrusting", "IsUgly", "IsUnfit",
"IsVengeful", "IsVisualImpaired", "IsWeakStomach"
};
private static bool _loggedDiag;
private static readonly HashSet<string> TraitTrainings = new HashSet<string>(StringComparer.Ordinal) { "Fit", "Strong", "Feeble", "Unfit" };
private static readonly Dictionary<string, (double val, double t)> _trainSeen = new Dictionary<string, (double, double)>(StringComparer.Ordinal);
private const double TrainRecentSeconds = 600.0;
private static HashSet<string>? _mttStatusNames;
private const int DISPLAY_ALWAYS = 2;
private static readonly Dictionary<string, bool> _needBackedCache = new Dictionary<string, bool>(StringComparer.Ordinal);
private static readonly Dictionary<string, double> _prevValues = new Dictionary<string, double>(StringComparer.Ordinal);
private static readonly Dictionary<string, TrendDirection> _lastTrend = new Dictionary<string, TrendDirection>(StringComparer.Ordinal);
private static string _trendCharId = string.Empty;
private const double TrendEpsilon = 0.25;
private static readonly Dictionary<string, bool> _invertedTrend = new Dictionary<string, bool>(StringComparer.Ordinal);
public static CharacterSnapshot? ReadPlayer()
{
CondOwner val;
try
{
val = CrewSim.GetSelectedCrew();
CondOwner coPlayer = CrewSim.coPlayer;
if ((Object)(object)val != (Object)null && (Object)(object)coPlayer != (Object)null && val != coPlayer)
{
bool flag;
try
{
JsonCompany company = coPlayer.Company;
flag = company != null && company.mapRoster?.ContainsKey(val.strID) == true;
}
catch (Exception)
{
flag = false;
}
if (!flag)
{
val = coPlayer;
}
}
}
catch (Exception ex2)
{
ModLog.Debug("ReadPlayer: CrewSim not ready (" + ex2.GetType().Name + ").");
return null;
}
if ((Object)(object)val == (Object)null || val.mapConds == null)
{
return null;
}
string text = val.strID ?? val.strName ?? string.Empty;
bool flag2 = text != _trendCharId;
if (flag2)
{
_trendCharId = text;
_prevValues.Clear();
_lastTrend.Clear();
}
EnsureMttStatusNames();
CharacterSnapshot characterSnapshot = new CharacterSnapshot
{
CharacterName = ((!string.IsNullOrEmpty(val.strNameFriendly)) ? val.strNameFriendly : (val.strName ?? "Unknown"))
};
try
{
characterSnapshot.InChargen = val.HasCond("IsInChargen");
}
catch (Exception)
{
characterSnapshot.InChargen = false;
}
foreach (Condition value in val.mapConds.Values)
{
if (value == null || string.IsNullOrEmpty(value.strName))
{
continue;
}
if (value.strName.StartsWith("Skill", StringComparison.Ordinal))
{
characterSnapshot.Skills.Add(new SkillEntry(CleanSkillName(value), learned: true, 0, DescOf(val, value)));
}
else if (value.strName.StartsWith("DcTraining", StringComparison.Ordinal))
{
if (TryReadTraining(val, value, out SkillEntry entry, out bool isTrait))
{
(isTrait ? characterSnapshot.TrainingTraits : characterSnapshot.TrainingSkills).Add(entry);
}
}
else if (TraitNames.Contains(value.strName))
{
characterSnapshot.Traits.Add(new TraitEntry(FriendlyName(value), PolarityOf(value), DescOf(val, value)));
}
else if (IsActiveStatus(value))
{
characterSnapshot.ActiveConditions.Add(new ConditionEntry(FriendlyName(value), ToneOf(value), TrendOf(val, value), DescOf(val, value)));
}
}
characterSnapshot.Skills.Sort((SkillEntry a, SkillEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
characterSnapshot.TrainingSkills.Sort((SkillEntry a, SkillEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
characterSnapshot.TrainingTraits.Sort((SkillEntry a, SkillEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
characterSnapshot.Traits.Sort((TraitEntry a, TraitEntry b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase));
characterSnapshot.ActiveConditions.Sort(delegate(ConditionEntry a, ConditionEntry b)
{
int num = ToneRank(a.Tone).CompareTo(ToneRank(b.Tone));
return (num == 0) ? string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase) : num;
});
if (flag2)
{
ModLog.Info("[diag] character switch → \"" + characterSnapshot.CharacterName + "\" (id=" + text + "): " + $"mapConds={val.mapConds.Count} skills={characterSnapshot.Skills.Count} " + $"trainSkills={characterSnapshot.TrainingSkills.Count} traits={characterSnapshot.Traits.Count} " + $"conditions={characterSnapshot.ActiveConditions.Count}");
}
LogDiagnosticsOnce(val, characterSnapshot);
return characterSnapshot;
}
private static void LogDiagnosticsOnce(CondOwner player, CharacterSnapshot s)
{
if (_loggedDiag)
{
return;
}
_loggedDiag = true;
ModLog.Info($"[diag] mapConds={player.mapConds.Count} skills={s.Skills.Count} " + $"trainSkills={s.TrainingSkills.Count} trainTraits={s.TrainingTraits.Count} " + $"traits={s.Traits.Count} conditions={s.ActiveConditions.Count}");
List<string> list = new List<string>();
foreach (ConditionEntry activeCondition in s.ActiveConditions)
{
list.Add(activeCondition.Name + "[" + activeCondition.Tone.ToString() + "]");
}
ModLog.Info(string.Format("[diag] active conditions ({0}): {1}", list.Count, string.Join(", ", list.ToArray())));
List<string> list2 = new List<string>();
foreach (Condition value in player.mapConds.Values)
{
if (value != null && value.strName != null && value.nDisplaySelf == 2 && !value.strName.StartsWith("Skill", StringComparison.Ordinal) && !value.strName.StartsWith("DcTraining", StringComparison.Ordinal) && !TraitNames.Contains(value.strName))
{
list2.Add($"{value.strName}(other={value.nDisplayOther},{value.strColor})");
}
}
list2.Sort();
ModLog.Info(string.Format("[diag] disp2 pool ({0}): {1}", list2.Count, string.Join(", ", list2.ToArray())));
}
private static bool TryReadTraining(CondOwner player, Condition cond, out SkillEntry entry, out bool isTrait)
{
entry = null;
string text = cond.strName.Substring("DcTraining".Length).TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
isTrait = TraitTrainings.Contains(text);
if (text.Length == 0)
{
return false;
}
string text2 = (isTrait ? ("Is" + text) : ("Skill" + text));
try
{
if (player.HasCond(text2))
{
return false;
}
}
catch (Exception)
{
}
double num;
try
{
num = player.GetCondAmount("StatTraining" + text);
}
catch (Exception)
{
num = 0.0;
}
int trainingPercent = (int)Math.Floor(Math.Max(0.0, Math.Min(100.0, num)));
entry = new SkillEntry(CleanTrainingName(cond, text), learned: false, trainingPercent, DescOf(player, cond));
entry.RecentlyTrained = IsRecentlyTrained(text, num);
return true;
}
private static bool IsRecentlyTrained(string suffix, double rawPct)
{
try
{
double fEpoch = StarSystem.fEpoch;
string key = _trendCharId + "|" + suffix;
if (_trainSeen.TryGetValue(key, out (double, double) value))
{
if (Math.Abs(rawPct - value.Item1) > 0.0001)
{
value = (rawPct, fEpoch);
_trainSeen[key] = value;
}
return fEpoch - value.Item2 <= 600.0;
}
_trainSeen[key] = (rawPct, double.NegativeInfinity);
return false;
}
catch (Exception)
{
return true;
}
}
private static string CleanTrainingName(Condition cond, string suffix)
{
string text = cond.strNameFriendly ?? string.Empty;
if (text.StartsWith("Training: ", StringComparison.OrdinalIgnoreCase))
{
text = text.Substring("Training: ".Length);
}
int num = text.LastIndexOf(' ');
if (num > 0 && text.EndsWith("%", StringComparison.Ordinal))
{
text = text.Substring(0, num);
}
text = text.Trim();
if (text.Length <= 0)
{
return Prettify(suffix);
}
return text;
}
private static void EnsureMttStatusNames()
{
if (_mttStatusNames != null)
{
return;
}
try
{
HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
string[] array = new string[2] { "CONDSocialGUIFilterDCs", "CONDSocialGUIFilterDCsMTT" };
for (int i = 0; i < array.Length; i++)
{
Loot loot = DataHandler.GetLoot(array[i]);
List<string> list = ((loot != null) ? loot.GetLootNames((string)null, false, (string)null) : null);
if (list == null || list.Count == 0)
{
return;
}
foreach (string item in list)
{
hashSet.Add(item);
}
}
_mttStatusNames = hashSet;
ModLog.Info($"MTT status filter loaded ({hashSet.Count} condition names).");
}
catch (Exception ex)
{
ModLog.Debug("MTT status filter unavailable (" + ex.GetType().Name + "); using heuristic only.");
}
}
private static bool IsActiveStatus(Condition cond)
{
if (cond.nDisplaySelf != 2)
{
return false;
}
if (_mttStatusNames != null && _mttStatusNames.Contains(cond.strName))
{
return true;
}
if (cond.nDisplayOther < 1)
{
return false;
}
if (cond.strName.StartsWith("Is", StringComparison.Ordinal))
{
return false;
}
if (cond.strName.StartsWith("Career", StringComparison.Ordinal))
{
return false;
}
if (cond.strName.StartsWith("Dc", StringComparison.Ordinal) && !IsNeedBacked(cond))
{
return false;
}
return true;
}
private static bool IsNeedBacked(Condition cond)
{
if (_needBackedCache.TryGetValue(cond.strName, out var value))
{
return value;
}
bool flag;
try
{
flag = (!string.IsNullOrEmpty(cond.strTrackCond) && DataHandler.GetCond(cond.strTrackCond) != null) || DataHandler.GetCond("Stat" + cond.strName.Substring(2).TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')) != null;
}
catch (Exception)
{
return true;
}
_needBackedCache[cond.strName] = flag;
return flag;
}
private static TraitPolarity PolarityOf(Condition cond)
{
if (string.Equals(cond.strColor, "Good", StringComparison.OrdinalIgnoreCase))
{
return TraitPolarity.Positive;
}
if (cond.bNegative || string.Equals(cond.strColor, "Bad", StringComparison.OrdinalIgnoreCase))
{
return TraitPolarity.Negative;
}
return TraitPolarity.Neutral;
}
private static int ToneRank(ConditionTone tone)
{
return tone switch
{
ConditionTone.Critical => 0,
ConditionTone.Warning => 1,
ConditionTone.Neutral => 2,
_ => 3,
};
}
private static ConditionTone ToneOf(Condition cond)
{
string text = cond.strColor ?? string.Empty;
if (text.StartsWith("Good", StringComparison.OrdinalIgnoreCase))
{
return ConditionTone.Good;
}
if (cond.bFatal || cond.bKO || cond.bAlert || string.Equals(text, "BadVery", StringComparison.OrdinalIgnoreCase))
{
return ConditionTone.Critical;
}
if (cond.bNegative || text.StartsWith("Bad", StringComparison.OrdinalIgnoreCase) || text.StartsWith("Cold", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Warning", StringComparison.OrdinalIgnoreCase))
{
return ConditionTone.Warning;
}
return ConditionTone.Neutral;
}
private static bool IsInvertedTrend(string trackKey)
{
if (string.IsNullOrEmpty(trackKey))
{
return false;
}
if (_invertedTrend.TryGetValue(trackKey, out var value))
{
return value;
}
bool flag = false;
try
{
if (DataHandler.dictConds != null)
{
foreach (JsonCond value2 in DataHandler.dictConds.Values)
{
if (value2.strTrackCond == trackKey && string.Equals(value2.strColor, "Good", StringComparison.OrdinalIgnoreCase))
{
flag = value2.bInvert;
break;
}
}
}
}
catch (Exception)
{
flag = false;
}
_invertedTrend[trackKey] = flag;
return flag;
}
private static TrendDirection TrendOf(CondOwner player, Condition cond)
{
string text = ((!string.IsNullOrEmpty(cond.strTrackCond)) ? cond.strTrackCond : cond.strName);
double num;
try
{
num = ((!string.IsNullOrEmpty(cond.strTrackCond)) ? player.GetCondAmount(cond.strTrackCond) : cond.fCount);
}
catch (Exception)
{
num = cond.fCount;
}
if (!_prevValues.TryGetValue(text, out var value))
{
_prevValues[text] = num;
_lastTrend[text] = TrendDirection.None;
return TrendDirection.None;
}
double num2 = num - value;
bool flag = IsInvertedTrend(text);
if (num2 >= 0.25)
{
_lastTrend[text] = ((!flag) ? TrendDirection.Up : TrendDirection.Down);
_prevValues[text] = num;
}
else if (num2 <= -0.25)
{
_lastTrend[text] = (flag ? TrendDirection.Up : TrendDirection.Down);
_prevValues[text] = num;
}
if (!_lastTrend.TryGetValue(text, out var value2))
{
return TrendDirection.None;
}
return value2;
}
private static string FriendlyName(Condition cond)
{
if (string.IsNullOrEmpty(cond.strNameFriendly))
{
return cond.strName;
}
return cond.strNameFriendly;
}
private static string DescOf(CondOwner player, Condition cond)
{
if (string.IsNullOrEmpty(cond.strDesc))
{
return string.Empty;
}
try
{
return GrammarUtils.GetInflectedString(cond.strDesc, (object)player);
}
catch (Exception)
{
return cond.strDesc;
}
}
private static string CleanSkillName(Condition cond)
{
string text = FriendlyName(cond);
if (text.StartsWith("Skilled in ", StringComparison.OrdinalIgnoreCase))
{
return text.Substring("Skilled in ".Length);
}
if (!string.IsNullOrEmpty(cond.strNameFriendly))
{
return text;
}
return Prettify(cond.strName.Substring("Skill".Length));
}
private static string Prettify(string raw)
{
if (string.IsNullOrEmpty(raw))
{
return raw;
}
StringBuilder stringBuilder = new StringBuilder(raw.Length + 4);
for (int i = 0; i < raw.Length; i++)
{
char c = raw[i];
if (i > 0 && char.IsUpper(c) && !char.IsUpper(raw[i - 1]))
{
stringBuilder.Append(' ');
}
stringBuilder.Append(c);
}
return stringBuilder.ToString();
}
}
public class CharacterSnapshot
{
public string CharacterName { get; set; } = string.Empty;
public bool InChargen { get; set; }
public List<SkillEntry> Skills { get; } = new List<SkillEntry>();
public List<SkillEntry> TrainingSkills { get; } = new List<SkillEntry>();
public List<SkillEntry> TrainingTraits { get; } = new List<SkillEntry>();
public List<TraitEntry> Traits { get; } = new List<TraitEntry>();
public List<ConditionEntry> ActiveConditions { get; } = new List<ConditionEntry>();
}
public class SkillEntry
{
public string Name { get; }
public bool Learned { get; }
public int TrainingPercent { get; }
public bool RecentlyTrained { get; set; }
public string Description { get; }
public SkillEntry(string name, bool learned, int trainingPercent = 0, string description = "")
{
Name = name;
Learned = learned;
TrainingPercent = trainingPercent;
Description = description;
}
}
public class TraitEntry
{
public string Name { get; }
public TraitPolarity Polarity { get; }
public string Description { get; }
public TraitEntry(string name, TraitPolarity polarity, string description = "")
{
Name = name;
Polarity = polarity;
Description = description;
}
}
public enum TraitPolarity
{
Positive,
Negative,
Neutral
}
public class ConditionEntry
{
public string Name { get; }
public ConditionTone Tone { get; }
public TrendDirection Trend { get; }
public string Description { get; }
public ConditionEntry(string name, ConditionTone tone, TrendDirection trend, string description = "")
{
Name = name;
Tone = tone;
Trend = trend;
Description = description;
}
}
public enum ConditionTone
{
Good,
Neutral,
Warning,
Critical
}
public enum TrendDirection
{
None,
Up,
Down
}
internal static class ModLog
{
internal static ManualLogSource? Log;
internal static void Info(string msg)
{
ManualLogSource? log = Log;
if (log != null)
{
log.LogInfo((object)msg);
}
}
internal static void Debug(string msg)
{
ManualLogSource? log = Log;
if (log != null)
{
log.LogDebug((object)msg);
}
}
internal static void Warn(string msg)
{
ManualLogSource? log = Log;
if (log != null)
{
log.LogWarning((object)msg);
}
}
}
}
namespace OstranautsSidebar.Core
{
internal static class Diagnostics
{
private static bool _done;
public static void DumpOnce()
{
if (_done)
{
return;
}
_done = true;
try
{
DumpCanvases();
GUIMegaToolTip obj = Object.FindFirstObjectByType<GUIMegaToolTip>();
DumpChain("GUIMegaToolTip", (obj != null) ? ((Component)obj).transform : null);
ModuleHost obj2 = Object.FindFirstObjectByType<ModuleHost>();
DumpChain("ModuleHost", (obj2 != null) ? ((Component)obj2).transform : null);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[diag] UI dump failed: " + ex.Message));
}
}
private static void DumpCanvases()
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
Canvas[] array = Object.FindObjectsByType<Canvas>((FindObjectsSortMode)0);
Array.Sort(array, (Canvas a, Canvas b) => a.sortingOrder.CompareTo(b.sortingOrder));
StringBuilder stringBuilder = new StringBuilder("[diag] canvases (name#order/mode): ");
Canvas[] array2 = array;
foreach (Canvas val in array2)
{
stringBuilder.Append($"{((Object)val).name}#{val.sortingOrder}/{val.renderMode} | ");
}
Plugin.Log.LogInfo((object)stringBuilder.ToString());
}
private static void DumpChain(string label, Transform? t)
{
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: 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)
if ((Object)(object)t == (Object)null)
{
Plugin.Log.LogInfo((object)("[diag] " + label + ": <not found>"));
return;
}
StringBuilder stringBuilder = new StringBuilder("[diag] " + label + " chain: ");
Transform val = t;
while ((Object)(object)val != (Object)null)
{
Canvas component = ((Component)val).GetComponent<Canvas>();
RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
stringBuilder.Append(((Object)val).name);
if ((Object)(object)component != (Object)null)
{
stringBuilder.Append($"[Canvas#{component.sortingOrder}]");
}
if ((Object)(object)((Component)val).GetComponent<CanvasGroup>() != (Object)null)
{
stringBuilder.Append("[CG]");
}
if ((Object)(object)val2 != (Object)null)
{
stringBuilder.Append($"{{aMin{val2.anchorMin} aMax{val2.anchorMax} sz{val2.sizeDelta} pos{val2.anchoredPosition}}}");
}
stringBuilder.Append(" < ");
val = val.parent;
}
Plugin.Log.LogInfo((object)stringBuilder.ToString());
}
}
internal static class HelmetLinkClient
{
private const string TypeName = "OstranautsHelmetHUD.HelmetLink";
private const int SupportedVersion = 1;
private static bool _resolved;
private static Func<bool>? _readoutActive;
private static Func<bool>? _helmetOn;
internal static bool Available
{
get
{
Resolve();
return _readoutActive != null;
}
}
internal static bool ReadoutActive
{
get
{
Resolve();
try
{
return _readoutActive != null && _readoutActive();
}
catch (Exception)
{
return false;
}
}
}
internal static bool HelmetOn
{
get
{
Resolve();
try
{
return _helmetOn != null && _helmetOn();
}
catch (Exception)
{
return false;
}
}
}
private static void Resolve()
{
if (_resolved)
{
return;
}
_resolved = true;
try
{
Type type = null;
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly assembly in assemblies)
{
try
{
type = assembly.GetType("OstranautsHelmetHUD.HelmetLink", throwOnError: false);
}
catch (Exception)
{
continue;
}
if (type != null)
{
break;
}
}
if (type == null)
{
Plugin.Log.LogInfo((object)"Helmet HUD not installed — the sidebar will use its own helmet check.");
return;
}
int num = 0;
FieldInfo field = type.GetField("Version", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.FieldType == typeof(int))
{
num = (int)(field.GetRawConstantValue() ?? ((object)0));
}
if (num != 1)
{
Plugin.Log.LogWarning((object)($"Helmet HUD is installed but exposes link contract v{num}, and this sidebar understands v{1}. " + "The two mods won't coordinate; the sidebar falls back to watching the helmet overlay itself. Updating both mods to the same release fixes it."));
return;
}
_readoutActive = Bind(type, "ReadoutActive");
_helmetOn = Bind(type, "HelmetOn");
if (_readoutActive != null)
{
Plugin.Log.LogInfo((object)$"Helmet HUD detected — sidebar will minimise while the helmet is up (link v{num}).");
}
}
catch (Exception ex2)
{
Plugin.Log.LogWarning((object)("Couldn't read the Helmet HUD link (" + ex2.GetType().Name + ": " + ex2.Message + "). The sidebar falls back to watching the helmet overlay itself."));
}
}
private static Func<bool>? Bind(Type t, string prop)
{
try
{
PropertyInfo property = t.GetProperty(prop, BindingFlags.Static | BindingFlags.Public);
MethodInfo methodInfo = property?.GetGetMethod();
if (methodInfo == null || property.PropertyType != typeof(bool))
{
return null;
}
return (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), methodInfo);
}
catch (Exception)
{
return null;
}
}
}
internal class MttWatcher
{
private RectTransform? _container;
private CanvasGroup? _cg;
private Canvas? _mttCanvas;
private float _lastAcquireTry;
private bool _loggedCollapsed;
private bool _loggedExpanded;
private static readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];
private float _lastMeasure;
private const float MeasureInterval = 0.5f;
private const float SettleWindow = 0.75f;
private float _fastUntil = float.NegativeInfinity;
private bool _prevOpen;
private bool _prevExpanded;
private static readonly List<Graphic> _graphicsBuf = new List<Graphic>(64);
private string _lowestName = "";
public bool Open { get; private set; }
public bool Expanded { get; private set; }
public float VisibleBottomScreenY { get; private set; } = -1f;
public void Refresh()
{
if ((Object)(object)_container == (Object)null)
{
if (Time.unscaledTime - _lastAcquireTry < 1f)
{
return;
}
_lastAcquireTry = Time.unscaledTime;
TryAcquire();
if ((Object)(object)_container == (Object)null)
{
return;
}
}
try
{
Open = ModuleHost.Opened;
}
catch
{
Open = (Object)(object)_cg != (Object)null && _cg.alpha > 0.5f;
}
try
{
Expanded = ModuleHost.ShowExpandedTooltip;
}
catch
{
Expanded = false;
}
if (Open != _prevOpen || Expanded != _prevExpanded)
{
_prevOpen = Open;
_prevExpanded = Expanded;
_fastUntil = Time.unscaledTime + 0.75f;
}
if (!Open)
{
VisibleBottomScreenY = -1f;
return;
}
bool flag = Time.unscaledTime < _fastUntil;
if (flag || Time.unscaledTime - _lastMeasure >= 0.5f)
{
_lastMeasure = Time.unscaledTime;
VisibleBottomScreenY = MeasureVisibleBottom();
if (!flag)
{
LogBottomOnce();
}
}
}
private float MeasureVisibleBottom()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014a: Unknown result type (might be due to invalid IL or missing references)
try
{
Camera val = (((Object)(object)_mttCanvas != (Object)null && (int)_mttCanvas.renderMode != 0) ? _mttCanvas.worldCamera : null);
_container.GetWorldCorners(_corners);
float y = RectTransformUtility.WorldToScreenPoint(val, _corners[0]).y;
float y2 = RectTransformUtility.WorldToScreenPoint(val, _corners[1]).y;
float num = Mathf.Max(1f, y2 - y);
float num2 = float.MaxValue;
bool flag = false;
((Component)_container).GetComponentsInChildren<Graphic>(false, _graphicsBuf);
foreach (Graphic item in _graphicsBuf)
{
if (!((Object)(object)item == (Object)null) && ((Behaviour)item).isActiveAndEnabled && item.color.a > 0.05f && ((Object)(object)item.canvasRenderer == (Object)null || (!item.canvasRenderer.cull && item.canvasRenderer.GetInheritedAlpha() > 0.05f)))
{
item.rectTransform.GetWorldCorners(_corners);
float bottom = RectTransformUtility.WorldToScreenPoint(val, _corners[0]).y;
float top = RectTransformUtility.WorldToScreenPoint(val, _corners[1]).y;
if (!(top - bottom >= 0.95f * num) && !ClipToAncestorMasks(((Component)item).transform, val, ref bottom, ref top) && bottom < num2)
{
num2 = bottom;
flag = true;
_lowestName = (((Object)(object)((Component)item).transform.parent != (Object)null) ? (((Object)((Component)item).transform.parent).name + "/") : "") + ((Object)item).name;
}
}
}
return flag ? num2 : (-1f);
}
catch (Exception)
{
return -1f;
}
}
private bool ClipToAncestorMasks(Transform element, Camera? cam, ref float bottom, ref float top)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
Transform parent = element.parent;
while ((Object)(object)parent != (Object)null)
{
if ((Object)(object)((Component)parent).GetComponent<RectMask2D>() != (Object)null || (Object)(object)((Component)parent).GetComponent<Mask>() != (Object)null)
{
RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if (val != null)
{
val.GetWorldCorners(_corners);
float y = RectTransformUtility.WorldToScreenPoint(cam, _corners[0]).y;
float y2 = RectTransformUtility.WorldToScreenPoint(cam, _corners[1]).y;
if (y > bottom)
{
bottom = y;
}
if (y2 < top)
{
top = y2;
}
if (top <= bottom + 0.5f)
{
return true;
}
}
}
if ((Object)(object)parent == (Object)(object)((Component)_container).transform)
{
break;
}
parent = parent.parent;
}
return false;
}
private void LogBottomOnce()
{
if (!(Expanded ? _loggedExpanded : _loggedCollapsed))
{
float num = Mathf.Max(1f, (float)Screen.height);
string text = (Expanded ? "EXPANDED" : "collapsed");
Plugin.Log.LogInfo((object)$"[diag] MTT {text}: visibleBottomFracFromTop={((VisibleBottomScreenY >= 0f) ? (1f - VisibleBottomScreenY / num) : (-1f)):F3} lowest={_lowestName} screenH={Screen.height}");
if (Expanded)
{
_loggedExpanded = true;
}
else
{
_loggedCollapsed = true;
}
}
}
private void TryAcquire()
{
try
{
GUIMegaToolTip val = Object.FindFirstObjectByType<GUIMegaToolTip>();
if (!((Object)(object)val == (Object)null))
{
CanvasGroup componentInParent = ((Component)val).GetComponentInParent<CanvasGroup>();
if (!((Object)(object)componentInParent == (Object)null))
{
_cg = componentInParent;
_container = ((Component)val).GetComponent<RectTransform>() ?? ((Component)componentInParent).GetComponent<RectTransform>();
_mttCanvas = ((Component)val).GetComponentInParent<Canvas>();
Plugin.Log.LogInfo((object)("[diag] MTT watcher attached (container=" + ((Object)_container).name + ", group=" + ((Object)componentInParent).name + ")."));
}
}
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("MTT acquire failed: " + ex.Message));
}
}
}
public class SidebarController : MonoBehaviour
{
private const float RefreshInterval = 0.5f;
private SidebarPanel? _panel;
private CharacterSnapshot? _lastData;
private float _timer;
private bool _userVisible = Plugin.StartVisible?.Value ?? true;
private bool _wasInChargen;
private readonly MttWatcher _mtt = new MttWatcher();
private float _lastMenuPoll;
private bool _menuOpen;
private static GUISaveLoadBase? _saveLoadUi;
private static GUIOptions? _optionsUi;
private static float _lastUiFind;
private static CanvasGroup? _encounterCg;
public static SidebarController? Instance { get; private set; }
private void Awake()
{
if ((Object)(object)Instance != (Object)null)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
else
{
Instance = this;
}
}
private void Update()
{
_timer += Time.unscaledDeltaTime;
if (!(_timer < 0.5f))
{
_timer = 0f;
Tick();
}
}
private bool MenuOpen()
{
if (Time.unscaledTime - _lastMenuPoll >= 0.2f)
{
_lastMenuPoll = Time.unscaledTime;
_menuOpen = DetectMenu();
}
return _menuOpen;
}
private static bool DetectMenu()
{
//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_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Invalid comparison between Unknown and I4
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Invalid comparison between Unknown and I4
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Invalid comparison between Unknown and I4
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Invalid comparison between Unknown and I4
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Invalid comparison between Unknown and I4
try
{
CanvasManager instance = CanvasManager.instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
GUIState state = instance.State;
if ((int)state == 3 || (int)state == 4 || (int)state == 2 || (int)state == 5 || (int)state == 6 || (int)state == 7)
{
return true;
}
if (EncounterShowing())
{
return true;
}
if (Plugin.HideWithHelmet.Value && HelmetShowing(instance))
{
return true;
}
if (CanvasManager.IsCanvasQuitShowing())
{
return true;
}
if (Time.unscaledTime - _lastUiFind >= 1f && ((Object)(object)_saveLoadUi == (Object)null || (Object)(object)_optionsUi == (Object)null))
{
_lastUiFind = Time.unscaledTime;
if ((Object)(object)_saveLoadUi == (Object)null)
{
_saveLoadUi = Object.FindFirstObjectByType<GUISaveLoadBase>();
}
if ((Object)(object)_optionsUi == (Object)null)
{
_optionsUi = Object.FindFirstObjectByType<GUIOptions>();
}
}
if (IsShownWithAlpha((Component?)(object)_saveLoadUi))
{
return true;
}
if (IsShownWithAlpha((Component?)(object)_optionsUi))
{
return true;
}
return false;
}
catch (Exception)
{
return false;
}
}
private static bool MinimiseForHelmet()
{
try
{
if (!Plugin.MinimiseWithHelmet.Value)
{
return false;
}
if (HelmetLinkClient.Available)
{
return HelmetLinkClient.HelmetOn;
}
CanvasManager instance = CanvasManager.instance;
return (Object)(object)instance != (Object)null && HelmetShowing(instance);
}
catch (Exception)
{
return false;
}
}
private static bool HelmetShowing(CanvasManager cm)
{
GameObject goCanvasHelmet = cm.goCanvasHelmet;
if ((Object)(object)goCanvasHelmet == (Object)null || !goCanvasHelmet.activeInHierarchy)
{
return false;
}
CanvasGroup component = goCanvasHelmet.GetComponent<CanvasGroup>();
if ((Object)(object)component != (Object)null)
{
return component.alpha > 0.5f;
}
return false;
}
private static bool EncounterShowing()
{
if ((Object)(object)_encounterCg == (Object)null)
{
GUISocialCombat2 val = Object.FindFirstObjectByType<GUISocialCombat2>();
Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.Find("pnlEncounter") : null);
_encounterCg = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<CanvasGroup>() : null);
}
if ((Object)(object)_encounterCg != (Object)null)
{
return IsShownWithAlpha((Component?)(object)_encounterCg);
}
return false;
}
private static bool IsShownWithAlpha(Component? c)
{
if ((Object)(object)c == (Object)null || !c.gameObject.activeInHierarchy)
{
return false;
}
CanvasGroup[] componentsInParent = c.GetComponentsInParent<CanvasGroup>();
for (int i = 0; i < componentsInParent.Length; i++)
{
if (componentsInParent[i].alpha <= 0.5f)
{
return false;
}
}
return true;
}
private void LateUpdate()
{
if ((Object)(object)_panel == (Object)null)
{
return;
}
_mtt.Refresh();
bool flag = MenuOpen();
bool flag2 = MinimiseForHelmet();
_panel.SetVisible(_userVisible && !flag && !flag2, !flag);
if (flag)
{
return;
}
if (!_mtt.Open)
{
_panel.SetHeightFraction(1f);
return;
}
float visibleBottomScreenY = _mtt.VisibleBottomScreenY;
if (visibleBottomScreenY > (float)Screen.height * 0.1f && visibleBottomScreenY < (float)Screen.height)
{
_panel.SetTopBelowScreenY(visibleBottomScreenY);
}
else
{
_panel.SetHeightFraction(_mtt.Expanded ? 0.29f : 0.64f);
}
}
private void Tick()
{
CharacterSnapshot characterSnapshot = (_lastData = CharacterDataReader.ReadPlayer());
if (characterSnapshot == null)
{
if ((Object)(object)_panel != (Object)null)
{
Object.Destroy((Object)(object)((Component)_panel).gameObject);
_panel = null;
Plugin.Log.LogInfo((object)"Player gone — sidebar panel removed.");
}
_wasInChargen = false;
return;
}
if (characterSnapshot.InChargen != _wasInChargen)
{
_wasInChargen = characterSnapshot.InChargen;
_userVisible = !characterSnapshot.InChargen && (Plugin.StartVisible?.Value ?? true);
_panel?.SetVisible(_userVisible);
}
if ((Object)(object)_panel == (Object)null)
{
_panel = SidebarPanel.Create();
_panel.SetVisible(_userVisible);
Plugin.Log.LogInfo((object)"Sidebar panel created.");
Diagnostics.DumpOnce();
}
_panel.Populate(characterSnapshot);
}
public void ToggleVisibility()
{
_userVisible = !_userVisible;
_panel?.SetVisible(_userVisible);
}
public void Destroy()
{
if ((Object)(object)_panel != (Object)null)
{
Object.Destroy((Object)(object)((Component)_panel).gameObject);
}
_panel = null;
Instance = null;
}
}
}