using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using FairyDust.Hud;
using FairyDust.Hud.Components.Deck;
using FairyDust.Hud.Configuration;
using FairyDust.Hud.Game.Services;
using FairyDust.Hud.Host;
using FairyDust.Hud.Modules.Status;
using FairyDust.Hud.Modules.Status.Bleed;
using FairyDust.Hud.Modules.Status.Entities;
using FairyDust.Hud.Modules.Status.Frostbite;
using FairyDust.Hud.Modules.Status.Infection;
using FairyDust.Hud.Modules.Status.Services;
using FairyDust.Hud.Modules.Status.Stamina;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppTMPro;
using Il2Cppmadeinfairyland.fairyengine;
using Il2Cppmadeinfairyland.fairyengine.actor.player;
using Il2Cppmadeinfairyland.forsakenfrontiers.actor.player;
using Il2Cppmadeinfairyland.forsakenfrontiers.actor.player.datadeck;
using Il2Cppmadeinfairyland.forsakenfrontiers.ui;
using MelonLoader;
using MelonLoader.Preferences;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "FairyDust.Hud", "1.0.0", "MadeInPG13Land", null)]
[assembly: MelonColor(255, 244, 155, 171)]
[assembly: MelonAuthorColor(255, 155, 126, 189)]
[assembly: MelonGame("made in fairyland", "Forsaken Frontiers")]
[assembly: MelonProcess("Forsaken Frontiers.exe")]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("FairyDust.Hud")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FairyDust.Hud")]
[assembly: AssemblyTitle("FairyDust.Hud")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FairyDust.Hud
{
public sealed class Main : MelonMod
{
private static Main activeInstance;
private GameplayHudHost hudHost;
private bool loggedLateUpdateFailure;
public override void OnInitializeMelon()
{
if (activeInstance != null && activeInstance != this)
{
activeInstance.hudHost?.Shutdown();
activeInstance.hudHost = null;
}
activeInstance = this;
Config.Initialize();
hudHost = new GameplayHudHost((MelonMod)(object)this);
hudHost.Register(new StatusBoardModule());
hudHost.Initialize();
((MelonBase)this).LoggerInstance.Msg(ConfigConsoleCard.Build());
}
public override void OnDeinitializeMelon()
{
hudHost?.Shutdown();
hudHost = null;
DeckStatusPanel.ReleaseSharedAssets();
if (activeInstance == this)
{
activeInstance = null;
}
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
hudHost?.OnSceneWasLoaded(buildIndex, sceneName);
}
public override void OnLateUpdate()
{
try
{
hudHost?.OnLateUpdate();
}
catch (Exception ex)
{
if (!loggedLateUpdateFailure)
{
loggedLateUpdateFailure = true;
((MelonBase)this).LoggerInstance.Error("HUD OnLateUpdate failed: " + ex);
}
}
}
}
public static class Metadata
{
public const string Name = "FairyDust.Hud";
public const string Version = "1.0.0";
public const string Author = "MadeInPG13Land";
}
}
namespace FairyDust.Hud.Modules.Status
{
internal sealed class StatusBoardModule : IHudModule
{
private static readonly TimeSpan TextStyleRefreshInterval = TimeSpan.FromSeconds(1.0);
private const float NormalBackgroundAlpha = 0.15f;
private readonly PlayerStatusReadService reads;
private readonly StatusBoardService board;
private readonly StatusVisibilityService visibility;
private readonly List<StatusRowSnapshot> rowBuffer;
private HudModuleContext context;
private DeckStatusPanelHandle panel;
private FFDataDeck lastDeck;
private DateTime nextTextStyleRefreshUtc = DateTime.MinValue;
private int lastAppliedVisibleRowCount = -1;
private Vector2 lastAppliedSlotSize = new Vector2(float.NaN, float.NaN);
public string SlotObjectName => "Slot_StatusBoard";
public StatusBoardModule()
{
//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)
reads = new PlayerStatusReadService();
StatusFormatterService formatter = new StatusFormatterService(reads);
board = new StatusBoardService(new IStatusProvider[4]
{
new BleedStatusModule().CreateProvider(reads, formatter),
new InfectionStatusModule().CreateProvider(reads, formatter),
new FrostbiteStatusModule().CreateProvider(reads, formatter),
new StaminaStatusModule().CreateProvider(reads, formatter)
});
visibility = new StatusVisibilityService(reads);
rowBuffer = new List<StatusRowSnapshot>(board.Capacity);
}
public void OnAttach(HudModuleContext ctx)
{
context = ctx;
}
public void OnSceneWasLoaded(int buildIndex, string sceneName)
{
TeardownPanel();
}
public void OnLateUpdate()
{
if ((Object)(object)context?.Slot == (Object)null)
{
return;
}
try
{
FFPlayer current = FairyLocalPlayer.Current;
FFDataDeck dataDeck = reads.GetDataDeck(current);
if (!visibility.ShouldShowBoard(current, dataDeck, board.Providers))
{
SafeSetVisible(visible: false);
return;
}
board.CollectRows(new StatusProviderContext(current, dataDeck), rowBuffer);
if (rowBuffer.Count == 0)
{
SafeSetVisible(visible: false);
return;
}
if (!((Component)context.Slot).gameObject.activeSelf)
{
((Component)context.Slot).gameObject.SetActive(true);
}
EnsureBuilt(context.Slot, dataDeck);
panel.SetVisible(visible: true);
panel.SetBackgroundAlpha(0.15f);
RefreshDeckFlavor(dataDeck);
ApplyRows(rowBuffer);
ApplySlotSize(panel.ApplyVisibleLayout());
}
catch
{
SafeSetVisible(visible: false);
}
}
private void EnsureBuilt(RectTransform slot, FFDataDeck deck)
{
if (!((Object)(object)slot == (Object)null) && (!panel.IsValid || !((Object)(object)panel.Root != (Object)null) || !((Object)(object)panel.Root.transform.parent == (Object)(object)((Component)slot).transform) || !((Object)(object)lastDeck == (Object)(object)deck)))
{
TeardownPanel();
lastDeck = deck;
panel = DeckStatusPanel.Build(slot, deck, "StatusBoard", board.Capacity);
}
}
private void ApplyRows(IReadOnlyList<StatusRowSnapshot> rows)
{
panel.ClearRows();
for (int i = 0; i < rows.Count; i++)
{
StatusRowSnapshot statusRowSnapshot = rows[i];
panel.SetRow(i, statusRowSnapshot.Label, statusRowSnapshot.Ratio, statusRowSnapshot.ValueText, statusRowSnapshot.Warning);
}
}
private void ApplySlotSize(int visibleRowCount)
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: 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)
LayoutElement val = ((Component)context.Slot).GetComponent<LayoutElement>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)context.Slot).gameObject.AddComponent<LayoutElement>();
}
Vector2 val2 = DeckStatusPanel.OuterSizeForRows(visibleRowCount);
if (visibleRowCount != lastAppliedVisibleRowCount || !(val2 == lastAppliedSlotSize))
{
lastAppliedVisibleRowCount = visibleRowCount;
lastAppliedSlotSize = val2;
val.preferredWidth = val2.x;
val.preferredHeight = val2.y;
context.Slot.sizeDelta = val2;
Transform parent = ((Transform)context.Slot).parent;
RectTransform val3 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if (val3 != null)
{
LayoutRebuilder.MarkLayoutForRebuild(val3);
}
LayoutRebuilder.MarkLayoutForRebuild(context.Slot);
}
}
private void SetVisible(bool visible)
{
panel.SetVisible(visible);
if ((Object)(object)context?.Slot != (Object)null)
{
((Component)context.Slot).gameObject.SetActive(visible);
}
}
private void SafeSetVisible(bool visible)
{
try
{
SetVisible(visible);
}
catch
{
}
}
private void TeardownPanel()
{
//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)
panel.Destroy();
panel = default(DeckStatusPanelHandle);
lastDeck = null;
nextTextStyleRefreshUtc = DateTime.MinValue;
lastAppliedVisibleRowCount = -1;
lastAppliedSlotSize = new Vector2(float.NaN, float.NaN);
}
private void RefreshDeckFlavor(FFDataDeck deck)
{
if (!((Object)(object)deck == (Object)null) && panel.IsValid)
{
DateTime utcNow = DateTime.UtcNow;
bool flag = utcNow >= nextTextStyleRefreshUtc;
if (flag)
{
nextTextStyleRefreshUtc = utcNow + TextStyleRefreshInterval;
}
panel.RefreshFlavor(deck, flag);
}
}
}
}
namespace FairyDust.Hud.Modules.Status.Stamina
{
internal sealed class StaminaStatusModule
{
public IStatusProvider CreateProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
return new StaminaStatusProvider(reads);
}
}
internal sealed class StaminaStatusProvider : IStatusProvider
{
private const float LowWarningRatio = 0.25f;
private readonly PlayerStatusReadService reads;
public string Id => "stamina";
public int SortOrder => 30;
public bool IsEnabled => Config.Values.StaminaModuleEnabled;
public StaminaStatusProvider(PlayerStatusReadService reads)
{
this.reads = reads;
}
public bool TryGetRow(StatusProviderContext context, out StatusRowSnapshot row)
{
float num = Mathf.Max(reads.MaxStamina(context.Player), 1E-05f);
float num2 = Mathf.Clamp01(reads.Stamina(context.Player) / num);
row = new StatusRowSnapshot(StatusRowKind.Stamina, Id, "STAMINA", num2, SortOrder, null, num2 <= 0.25f);
return true;
}
}
}
namespace FairyDust.Hud.Modules.Status.Services
{
internal sealed class PlayerStatusReadService
{
public bool IsUsable(FFPlayer player)
{
if ((Object)(object)player == (Object)null)
{
return false;
}
try
{
return (Object)(object)((Component)player).gameObject != (Object)null && ((Component)player).gameObject.activeInHierarchy;
}
catch
{
return false;
}
}
public FFDataDeck GetDataDeck(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.DataDeck : null;
}
catch
{
return null;
}
}
public bool IsDataDeckOpen(FFDataDeck deck)
{
try
{
return (Object)(object)deck != (Object)null && deck.DataDeckOpen;
}
catch
{
return false;
}
}
public bool IsBleeding(FFPlayer player)
{
try
{
return (Object)(object)player != (Object)null && player.IsBleeding;
}
catch
{
return false;
}
}
public bool IsInfected(FFPlayer player)
{
try
{
return (Object)(object)player != (Object)null && player.Infected;
}
catch
{
return false;
}
}
public bool IsFrostbiteActive(FFPlayer player)
{
try
{
return (Object)(object)player != (Object)null && player.FrostbiteActive;
}
catch
{
return false;
}
}
public float BleedToDeathTime(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.BleedToDeathTime : 0f;
}
catch
{
return 0f;
}
}
public float BleedToDeathTimer(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.BleedToDeathTimer : 0f;
}
catch
{
return 0f;
}
}
public float InfectionTakeoverDuration(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.InfectionTakeoverDuration : 0f;
}
catch
{
return 0f;
}
}
public float InfectionTimer(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.InfectionTimer : 0f;
}
catch
{
return 0f;
}
}
public float MaxFrostbite(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.maxFrostbite : 0f;
}
catch
{
return 0f;
}
}
public float Frostbite(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.Frostbite : 0f;
}
catch
{
return 0f;
}
}
public float FrostbiteSpeed(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? player.frostbiteSpeed : 0f;
}
catch
{
return 0f;
}
}
public float MaxStamina(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? ((FairyPlayer)player).MaxStamina : 0f;
}
catch
{
return 0f;
}
}
public float Stamina(FFPlayer player)
{
try
{
return ((Object)(object)player != (Object)null) ? ((FairyPlayer)player).Stamina : 0f;
}
catch
{
return 0f;
}
}
}
internal sealed class StatusBoardService
{
private readonly IStatusProvider[] providers;
public IReadOnlyList<IStatusProvider> Providers => providers;
public int Capacity => providers.Length;
public StatusBoardService(IEnumerable<IStatusProvider> providers)
{
this.providers = providers.OrderBy((IStatusProvider provider) => provider.SortOrder).ToArray();
}
public void CollectRows(StatusProviderContext context, List<StatusRowSnapshot> rows)
{
rows.Clear();
for (int i = 0; i < providers.Length; i++)
{
IStatusProvider statusProvider = providers[i];
if (statusProvider.IsEnabled && statusProvider.TryGetRow(context, out var row))
{
rows.Add(row);
}
}
rows.Sort((StatusRowSnapshot left, StatusRowSnapshot right) => left.SortOrder.CompareTo(right.SortOrder));
}
}
internal sealed class StatusFormatterService
{
private readonly PlayerStatusReadService reads;
public StatusFormatterService(PlayerStatusReadService reads)
{
this.reads = reads;
}
public string Timer(float seconds)
{
int num = Mathf.Max(0, Mathf.CeilToInt(seconds));
int value = num / 60;
int value2 = num % 60;
return $"{value:00}:{value2:00}";
}
public string FrostbiteValue(FFPlayer player, float frostbite, float maxFrostbite)
{
float num = reads.FrostbiteSpeed(player);
if (reads.IsFrostbiteActive(player) && num > 0.001f && frostbite < maxFrostbite)
{
return Timer((maxFrostbite - frostbite) / num);
}
return Mathf.RoundToInt(Mathf.Clamp01(frostbite / Mathf.Max(maxFrostbite, 1E-05f)) * 100f) + "%";
}
}
internal sealed class StatusVisibilityService
{
private readonly PlayerStatusReadService reads;
public StatusVisibilityService(PlayerStatusReadService reads)
{
this.reads = reads;
}
public bool ShouldShowBoard(FFPlayer player, FFDataDeck deck, IReadOnlyList<IStatusProvider> providers)
{
if (!reads.IsUsable(player) || reads.IsDataDeckOpen(deck))
{
return false;
}
for (int i = 0; i < providers.Count; i++)
{
if (providers[i].IsEnabled)
{
return true;
}
}
return false;
}
}
}
namespace FairyDust.Hud.Modules.Status.Infection
{
internal sealed class InfectionStatusModule
{
public IStatusProvider CreateProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
return new InfectionStatusProvider(reads, formatter);
}
}
internal sealed class InfectionStatusProvider : IStatusProvider
{
private const float LowWarningRatio = 0.25f;
private readonly PlayerStatusReadService reads;
private readonly StatusFormatterService formatter;
public string Id => "infection";
public int SortOrder => 10;
public bool IsEnabled => Config.Values.InfectionModuleEnabled;
public InfectionStatusProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
this.reads = reads;
this.formatter = formatter;
}
public bool TryGetRow(StatusProviderContext context, out StatusRowSnapshot row)
{
row = default(StatusRowSnapshot);
if (!reads.IsInfected(context.Player))
{
return false;
}
float num = Mathf.Max(reads.InfectionTakeoverDuration(context.Player), 1E-05f);
float num2 = Mathf.Max(0f, reads.InfectionTimer(context.Player));
float num3 = Mathf.Clamp01(num2 / num);
row = new StatusRowSnapshot(StatusRowKind.Infection, Id, "INFECTION", num3, SortOrder, formatter.Timer(num2), num3 <= 0.25f);
return true;
}
}
}
namespace FairyDust.Hud.Modules.Status.Frostbite
{
internal sealed class FrostbiteStatusModule
{
public IStatusProvider CreateProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
return new FrostbiteStatusProvider(reads, formatter);
}
}
internal sealed class FrostbiteStatusProvider : IStatusProvider
{
private const float HighWarningRatio = 0.75f;
private readonly PlayerStatusReadService reads;
private readonly StatusFormatterService formatter;
public string Id => "frostbite";
public int SortOrder => 20;
public bool IsEnabled => Config.Values.FrostbiteModuleEnabled;
public FrostbiteStatusProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
this.reads = reads;
this.formatter = formatter;
}
public bool TryGetRow(StatusProviderContext context, out StatusRowSnapshot row)
{
row = default(StatusRowSnapshot);
float num = Mathf.Max(reads.MaxFrostbite(context.Player), 1E-05f);
float num2 = Mathf.Clamp(reads.Frostbite(context.Player), 0f, num);
if (!reads.IsFrostbiteActive(context.Player) && !(num2 > 0.01f))
{
return false;
}
float num3 = Mathf.Clamp01(num2 / num);
row = new StatusRowSnapshot(StatusRowKind.Frostbite, Id, "FROSTBITE", num3, SortOrder, formatter.FrostbiteValue(context.Player, num2, num), num3 >= 0.75f);
return true;
}
}
}
namespace FairyDust.Hud.Modules.Status.Entities
{
internal interface IStatusProvider
{
string Id { get; }
int SortOrder { get; }
bool IsEnabled { get; }
bool TryGetRow(StatusProviderContext context, out StatusRowSnapshot row);
}
internal readonly struct StatusProviderContext
{
public FFPlayer Player { get; }
public FFDataDeck Deck { get; }
public StatusProviderContext(FFPlayer player, FFDataDeck deck)
{
Player = player;
Deck = deck;
}
}
internal enum StatusRowKind
{
Bleed,
Infection,
Frostbite,
Stamina
}
internal readonly struct StatusRowSnapshot
{
public StatusRowKind Kind { get; }
public string Id { get; }
public string Label { get; }
public float Ratio { get; }
public int SortOrder { get; }
public string ValueText { get; }
public bool Warning { get; }
public StatusRowSnapshot(StatusRowKind kind, string id, string label, float ratio, int sortOrder, string valueText = null, bool warning = false)
{
Kind = kind;
Id = id;
Label = label;
Ratio = Mathf.Clamp01(ratio);
SortOrder = sortOrder;
ValueText = valueText;
Warning = warning;
}
}
}
namespace FairyDust.Hud.Modules.Status.Bleed
{
internal sealed class BleedStatusModule
{
public IStatusProvider CreateProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
return new BleedStatusProvider(reads, formatter);
}
}
internal sealed class BleedStatusProvider : IStatusProvider
{
private const float LowWarningRatio = 0.25f;
private readonly PlayerStatusReadService reads;
private readonly StatusFormatterService formatter;
public string Id => "bleed";
public int SortOrder => 0;
public bool IsEnabled => Config.Values.BleedOutModuleEnabled;
public BleedStatusProvider(PlayerStatusReadService reads, StatusFormatterService formatter)
{
this.reads = reads;
this.formatter = formatter;
}
public bool TryGetRow(StatusProviderContext context, out StatusRowSnapshot row)
{
row = default(StatusRowSnapshot);
if (!reads.IsBleeding(context.Player))
{
return false;
}
float num = Mathf.Max(reads.BleedToDeathTime(context.Player), 1E-05f);
float num2 = Mathf.Max(0f, reads.BleedToDeathTimer(context.Player));
float num3 = Mathf.Clamp01(num2 / num);
row = new StatusRowSnapshot(StatusRowKind.Bleed, Id, "BLEED", num3, SortOrder, formatter.Timer(num2), num3 <= 0.25f);
return true;
}
}
}
namespace FairyDust.Hud.Host
{
internal sealed class GameplayHudHost
{
private const string RigObjectName = "FairyDust_HudRig";
private const string CanvasObjectName = "FairyDust_GameHud";
private const string DockObjectName = "FairyDust_HudDock";
private readonly MelonMod hostMod;
private readonly List<IHudModule> modules = new List<IHudModule>();
private GameObject hudRig;
private GameObject canvasRoot;
private Canvas hudCanvas;
private CanvasScaler hudCanvasScaler;
private RectTransform dockRoot;
private VerticalLayoutGroup dockLayoutGroup;
private Vector2 lastDockPosition = new Vector2(float.NaN, float.NaN);
private float lastDockSpacing = float.NaN;
private bool disposed;
private DateTime nextConfigReloadCheckUtc = DateTime.MinValue;
private bool loggedConfigReloadFailure;
public GameplayHudHost(MelonMod hostMod)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
this.hostMod = hostMod;
}
public void Register(IHudModule module)
{
modules.Add(module);
}
public void Initialize()
{
BuildCanvasAndDock();
for (int i = 0; i < modules.Count; i++)
{
IHudModule hudModule = modules[i];
HudModuleContext context = new HudModuleContext(CreateModuleSlot(dockRoot, hudModule.SlotObjectName), hostMod);
hudModule.OnAttach(context);
}
}
public void OnSceneWasLoaded(int buildIndex, string sceneName)
{
WorldSceneGate.OnSceneWasLoaded(buildIndex, sceneName);
for (int i = 0; i < modules.Count; i++)
{
modules[i].OnSceneWasLoaded(buildIndex, sceneName);
}
}
public void OnLateUpdate()
{
if (disposed)
{
return;
}
ReloadConfigIfDue();
if (!Config.Values.Enabled)
{
SetCanvasActive(on: false);
return;
}
if (!WorldSceneGate.IsActiveGameplayScene)
{
SetCanvasActive(on: false);
return;
}
SetCanvasActive(on: true);
UpdateDockLayout();
for (int i = 0; i < modules.Count; i++)
{
modules[i].OnLateUpdate();
}
}
private void ReloadConfigIfDue()
{
DateTime utcNow = DateTime.UtcNow;
if (utcNow < nextConfigReloadCheckUtc)
{
return;
}
nextConfigReloadCheckUtc = utcNow + TimeSpan.FromSeconds(1.0);
try
{
if (Config.ReloadIfChanged())
{
loggedConfigReloadFailure = false;
}
}
catch (Exception ex)
{
if (!loggedConfigReloadFailure)
{
loggedConfigReloadFailure = true;
((MelonBase)hostMod).LoggerInstance.Warning("HUD config reload failed: " + ex);
}
}
}
private void SetCanvasActive(bool on)
{
if ((Object)(object)hudRig != (Object)null)
{
hudRig.SetActive(on);
}
}
private void UpdateDockLayout()
{
//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_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: 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_0053: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)dockRoot == (Object)null))
{
Vector2 val = default(Vector2);
((Vector2)(ref val))..ctor(24f, 24f);
bool flag = false;
if (dockRoot.anchoredPosition != val)
{
dockRoot.anchoredPosition = val;
flag = true;
}
if (val != lastDockPosition)
{
lastDockPosition = val;
flag = true;
}
if ((Object)(object)dockLayoutGroup != (Object)null && !Mathf.Approximately(((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).spacing, 8f))
{
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).spacing = 8f;
flag = true;
}
if (!Mathf.Approximately(lastDockSpacing, 8f))
{
lastDockSpacing = 8f;
flag = true;
}
if (flag)
{
LayoutRebuilder.MarkLayoutForRebuild(dockRoot);
}
}
}
private void BuildCanvasAndDock()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Expected O, but got Unknown
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
//IL_008f: 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_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Expected O, but got Unknown
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_01ad: 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_0236: Expected O, but got Unknown
//IL_0249: Unknown result type (might be due to invalid IL or missing references)
//IL_024e: Unknown result type (might be due to invalid IL or missing references)
DestroyExistingRig();
hudRig = new GameObject("FairyDust_HudRig");
Object.DontDestroyOnLoad((Object)(object)hudRig);
canvasRoot = new GameObject("FairyDust_GameHud");
canvasRoot.transform.SetParent(hudRig.transform, false);
Canvas val = (hudCanvas = canvasRoot.AddComponent<Canvas>());
val.renderMode = (RenderMode)0;
val.worldCamera = null;
val.overrideSorting = true;
val.sortingOrder = 99;
val.pixelPerfect = false;
RectTransform component = canvasRoot.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.pivot = new Vector2(0.5f, 0.5f);
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
CanvasScaler val2 = (hudCanvasScaler = canvasRoot.AddComponent<CanvasScaler>());
val2.uiScaleMode = (ScaleMode)1;
val2.referenceResolution = new Vector2(1920f, 1080f);
val2.matchWidthOrHeight = 0.5f;
canvasRoot.AddComponent<GraphicRaycaster>().blockingObjects = (BlockingObjects)0;
GameObject val3 = new GameObject("FairyDust_HudDock");
val3.transform.SetParent(canvasRoot.transform, false);
val3.layer = 31;
dockRoot = val3.AddComponent<RectTransform>();
dockRoot.anchorMin = new Vector2(0f, 0f);
dockRoot.anchorMax = new Vector2(0f, 0f);
dockRoot.pivot = new Vector2(0f, 0f);
dockRoot.anchoredPosition = new Vector2(24f, 24f);
ContentSizeFitter obj = val3.AddComponent<ContentSizeFitter>();
obj.horizontalFit = (FitMode)2;
obj.verticalFit = (FitMode)2;
dockLayoutGroup = val3.AddComponent<VerticalLayoutGroup>();
((LayoutGroup)dockLayoutGroup).childAlignment = (TextAnchor)6;
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).childControlWidth = false;
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).childControlHeight = false;
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).childForceExpandHeight = false;
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).spacing = 8f;
((LayoutGroup)dockLayoutGroup).padding = new RectOffset(0, 0, 0, 0);
((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).reverseArrangement = false;
lastDockPosition = dockRoot.anchoredPosition;
lastDockSpacing = ((HorizontalOrVerticalLayoutGroup)dockLayoutGroup).spacing;
}
public void Shutdown()
{
disposed = true;
if ((Object)(object)hudRig != (Object)null)
{
hudRig.SetActive(false);
Object.Destroy((Object)(object)hudRig);
hudRig = null;
}
canvasRoot = null;
dockRoot = null;
dockLayoutGroup = null;
}
private static RectTransform CreateModuleSlot(RectTransform dock, string objectName)
{
//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: 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_0042: 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_0061: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(objectName);
val.transform.SetParent((Transform)(object)dock, false);
val.layer = 31;
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = new Vector2(0f, 0f);
val2.anchorMax = new Vector2(0f, 0f);
val2.pivot = new Vector2(0f, 0f);
val.AddComponent<LayoutElement>();
CanvasGroup obj = val.AddComponent<CanvasGroup>();
obj.alpha = 1f;
obj.interactable = false;
obj.blocksRaycasts = false;
return val2;
}
private static void DestroyExistingRig()
{
GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit(Object.FindObjectsOfType<GameObject>(true));
if (array == null)
{
return;
}
foreach (GameObject val in array)
{
if (!((Object)(object)val == (Object)null) && !(((Object)val).name != "FairyDust_HudRig"))
{
Object.Destroy((Object)(object)val);
}
}
}
}
internal static class HudDockLayout
{
public const int CanvasSortingOrder = 99;
public const int HudRenderLayer = 31;
public const float HudCameraDepth = 1f;
public const int MarginLeft = 24;
public const int MarginBottom = 24;
public const int ModuleStackSpacing = 8;
}
public sealed class HudModuleContext
{
public RectTransform Slot { get; }
public MelonMod HostMod { get; }
public HudModuleContext(RectTransform slot, MelonMod hostMod)
{
Slot = slot;
HostMod = hostMod;
}
}
public interface IHudModule
{
string SlotObjectName { get; }
void OnAttach(HudModuleContext context);
void OnSceneWasLoaded(int buildIndex, string sceneName);
void OnLateUpdate();
}
internal static class WorldSceneGate
{
public const string ForsakenWorldSceneName = "Forsaken Frontiers";
private static string activeSceneName = string.Empty;
public static bool IsForsakenWorldLoaded => string.Equals(activeSceneName, "Forsaken Frontiers", StringComparison.Ordinal);
public static bool IsActiveGameplayScene
{
get
{
//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)
Scene activeScene = SceneManager.GetActiveScene();
return string.Equals(((Scene)(ref activeScene)).name, "Forsaken Frontiers", StringComparison.Ordinal);
}
}
public static void OnSceneWasLoaded(int buildIndex, string sceneName)
{
activeSceneName = sceneName ?? string.Empty;
}
}
}
namespace FairyDust.Hud.Game.Services
{
internal static class FairyLocalPlayer
{
public static FFPlayer Current
{
get
{
FairyPlayer localPlayer = FairyEngine.LocalPlayer;
if (localPlayer == null)
{
return null;
}
return ((Il2CppObjectBase)localPlayer).TryCast<FFPlayer>();
}
}
}
}
namespace FairyDust.Hud.Configuration
{
public static class Config
{
private static MelonPreferences_ReflectiveCategory category;
private static readonly HashSet<string> LoggedInvalidConfigEntries = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private static DateTime lastLoadedWriteTimeUtc = DateTime.MinValue;
public static string FilePath { get; private set; } = string.Empty;
public static ModConfiguration Values { get; private set; } = new ModConfiguration();
public static void Initialize()
{
HudEnvironment.EnsureUserDataDirectory();
FilePath = HudEnvironment.ConfigFilePath;
bool num = File.Exists(FilePath);
category = MelonPreferences.CreateCategory<ModConfiguration>("FairyDust.Hud", (string)null);
category.SetFilePath(FilePath, false, false);
category.LoadFromFile(false);
category.DestroyFileWatcher();
Values = LoadValuesFromFile();
lastLoadedWriteTimeUtc = GetConfigWriteTimeUtc();
if (!num)
{
Save();
Values = LoadValuesFromFile();
lastLoadedWriteTimeUtc = GetConfigWriteTimeUtc();
}
}
public static void Save()
{
GetCategory().SaveToFile(false);
lastLoadedWriteTimeUtc = GetConfigWriteTimeUtc();
}
public static bool ReloadIfChanged()
{
DateTime configWriteTimeUtc = GetConfigWriteTimeUtc();
if (configWriteTimeUtc == DateTime.MinValue || configWriteTimeUtc <= lastLoadedWriteTimeUtc)
{
return false;
}
Values = LoadValuesFromFile();
lastLoadedWriteTimeUtc = configWriteTimeUtc;
return true;
}
private static ModConfiguration LoadValuesFromFile()
{
ModConfiguration modConfiguration = new ModConfiguration();
ApplyFileOverrides(modConfiguration);
return modConfiguration;
}
private static void ApplyFileOverrides(ModConfiguration values)
{
if (File.Exists(FilePath))
{
Dictionary<string, string> entries = ReadSection(FilePath, "FairyDust.Hud");
ApplyBool(entries, "Enabled", delegate(bool value)
{
values.Enabled = value;
});
ApplyBool(entries, "StaminaModuleEnabled", delegate(bool value)
{
values.StaminaModuleEnabled = value;
});
ApplyBool(entries, "BleedOutModuleEnabled", delegate(bool value)
{
values.BleedOutModuleEnabled = value;
});
ApplyBool(entries, "InfectionModuleEnabled", delegate(bool value)
{
values.InfectionModuleEnabled = value;
});
ApplyBool(entries, "FrostbiteModuleEnabled", delegate(bool value)
{
values.FrostbiteModuleEnabled = value;
});
}
}
private static Dictionary<string, string> ReadSection(string path, string sectionName)
{
Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
bool flag = false;
foreach (string item in File.ReadLines(path))
{
string text = item.Trim();
if (text.Length == 0 || text.StartsWith("#") || text.StartsWith(";"))
{
continue;
}
if (text.StartsWith("[") && text.EndsWith("]"))
{
flag = string.Equals(text.Substring(1, text.Length - 2).Trim(), sectionName, StringComparison.OrdinalIgnoreCase);
}
else if (flag)
{
int num = text.IndexOf('=');
if (num > 0)
{
string key = text.Substring(0, num).Trim();
string value = text.Substring(num + 1).Trim();
dictionary[key] = value;
}
}
}
return dictionary;
}
private static void ApplyBool(Dictionary<string, string> entries, string key, Action<bool> apply)
{
if (!entries.TryGetValue(key, out var value))
{
return;
}
if (bool.TryParse(value, out var result))
{
apply(result);
return;
}
string item = key + "=" + value;
if (LoggedInvalidConfigEntries.Add(item))
{
MelonLogger.Warning("[FairyDust.Hud] Ignoring invalid bool config value for " + key + ": " + value);
}
}
private static DateTime GetConfigWriteTimeUtc()
{
try
{
return File.Exists(FilePath) ? File.GetLastWriteTimeUtc(FilePath) : DateTime.MinValue;
}
catch
{
return DateTime.MinValue;
}
}
private static MelonPreferences_ReflectiveCategory GetCategory()
{
return category ?? throw new InvalidOperationException("Config.Initialize() must be called before saving preferences.");
}
}
internal static class ConfigConsoleCard
{
private const int Width = 58;
private static readonly string Border = "+" + new string('-', 58) + "+";
public static string Build()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendLine();
stringBuilder.AppendLine(Border);
stringBuilder.AppendLine(RowCentered("FairyDust.Hud"));
stringBuilder.AppendLine(Border);
stringBuilder.AppendLine(RowKeyValue("Version", "1.0.0"));
stringBuilder.AppendLine(RowKeyValue("File", DisplayConfigPath()));
stringBuilder.AppendLine(Border);
stringBuilder.AppendLine(RowText("Status Modules"));
stringBuilder.AppendLine(RowText(string.Empty));
stringBuilder.AppendLine(RowSetting(Config.Values.Enabled, "HUD"));
stringBuilder.AppendLine(RowSetting(Config.Values.StaminaModuleEnabled, "Stamina"));
stringBuilder.AppendLine(RowSetting(Config.Values.BleedOutModuleEnabled, "Bleed Out"));
stringBuilder.AppendLine(RowSetting(Config.Values.InfectionModuleEnabled, "Infection"));
stringBuilder.AppendLine(RowSetting(Config.Values.FrostbiteModuleEnabled, "Frostbite"));
stringBuilder.AppendLine(Border);
stringBuilder.AppendLine(RowText("Auto-reload is active. Changes apply while in game."));
stringBuilder.Append(Border);
return stringBuilder.ToString();
}
private static string DisplayConfigPath()
{
try
{
string userDataDirectory = HudEnvironment.UserDataDirectory;
string filePath = Config.FilePath;
if (!string.IsNullOrEmpty(userDataDirectory) && !string.IsNullOrEmpty(filePath) && filePath.StartsWith(userDataDirectory, StringComparison.OrdinalIgnoreCase))
{
string fileName = Path.GetFileName(filePath);
if (!string.IsNullOrEmpty(fileName))
{
return Path.Combine("UserData", fileName);
}
}
}
catch
{
}
return Config.FilePath;
}
private static string RowSetting(bool enabled, string label)
{
return RowText(" " + (enabled ? "[ON] " : "[OFF] ") + label);
}
private static string RowKeyValue(string key, string value)
{
return RowText(key.PadRight(9) + (value ?? string.Empty));
}
private static string RowCentered(string value)
{
if (value == null)
{
value = string.Empty;
}
if (value.Length >= 58)
{
return RowText(value);
}
int count = (58 - value.Length) / 2;
return RowText(new string(' ', count) + value);
}
private static string RowText(string value)
{
if (value == null)
{
value = string.Empty;
}
if (value.Length > 0 && !char.IsWhiteSpace(value[0]))
{
value = " " + value;
}
if (value.Length > 58)
{
value = value.Substring(0, 58);
}
return "|" + value.PadRight(58) + "|";
}
}
public static class HudEnvironment
{
private static string _modDir;
private static string _userDataDir;
public static string BaseDirectory => AppContext.BaseDirectory;
public static string GameRootDirectory => BaseDirectory;
public static string ModAssemblyDirectory
{
get
{
object obj = _modDir;
if (obj == null)
{
obj = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty;
_modDir = (string)obj;
}
return (string)obj;
}
}
public static string ModsDirectory => Path.Combine(BaseDirectory, "Mods");
public static string UserDataDirectory => _userDataDir ?? (_userDataDir = ResolveMelonUserDataDirectory());
public static string MelonLoaderDirectory => Path.Combine(BaseDirectory, "MelonLoader");
public static string Il2CppAssembliesDirectory => Path.Combine(MelonLoaderDirectory, "Il2CppAssemblies");
public static string ConfigFilePath => Path.Combine(UserDataDirectory, "FairyDust.Hud.cfg");
private static string ResolveMelonUserDataDirectory()
{
try
{
Type type = typeof(MelonMod).Assembly.GetType("MelonLoader.MelonUtils");
if (type != null)
{
string staticString = GetStaticString(type, "UserDataDirectory");
if (!string.IsNullOrEmpty(staticString))
{
return staticString;
}
string staticString2 = GetStaticString(type, "GameDirectory");
if (!string.IsNullOrEmpty(staticString2))
{
return Path.Combine(staticString2, "UserData");
}
}
}
catch
{
}
return Path.Combine(BaseDirectory, "UserData");
}
private static string GetStaticString(Type t, string name)
{
return t.GetProperty(name, BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as string;
}
public static void EnsureUserDataDirectory()
{
Directory.CreateDirectory(UserDataDirectory);
}
}
public sealed class ModConfiguration
{
public bool Enabled = true;
public bool StaminaModuleEnabled = true;
public bool BleedOutModuleEnabled = true;
public bool InfectionModuleEnabled = true;
public bool FrostbiteModuleEnabled = true;
}
}
namespace FairyDust.Hud.Components.Deck
{
internal static class DeckStatusPanel
{
public const int DefaultRowCapacity = 4;
public const float StrokePx = 2f;
public const float PadPx = 7f;
public const float RowHeightPx = 36f;
public const float LabelWidthPx = 132f;
public const float BarWidthPx = 136f;
public const float BarHeightPx = 13f;
public const float ValueWidthPx = 68f;
public const float LabelHeightPx = 21f;
private static readonly Color PanelBackground = new Color(0f, 0f, 0f, 0.15f);
internal static readonly Color TrackColor = new Color(0.02f, 0.02f, 0.02f, 0.06f);
private static readonly Color EmptyValueColor = new Color(1f, 1f, 1f, 0f);
private static Sprite whiteUnitSprite;
private static Texture2D whiteUnitTexture;
public static Vector2 PreferredOuterSize => OuterSizeForRows(4);
public static Vector2 OuterSizeForRows(int visibleRowCount)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
return new Vector2(354f, 18f + 36f * (float)Mathf.Max(1, visibleRowCount));
}
public static DeckStatusPanelHandle Build(RectTransform slot, FFDataDeck deck, string rootName, int rowCapacity)
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: 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_0059: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: 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_00ce: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
rowCapacity = Mathf.Max(1, rowCapacity);
List<Image> list = new List<Image>();
List<TextMeshProUGUI> list2 = new List<TextMeshProUGUI>();
GameObject val = CreateChild(rootName, (Transform)(object)slot);
RectTransform obj = val.AddComponent<RectTransform>();
obj.anchorMin = Vector2.zero;
obj.anchorMax = Vector2.one;
obj.offsetMin = Vector2.zero;
obj.offsetMax = Vector2.zero;
Image val2 = CreateImage("Background", val.transform, PanelBackground);
RectTransform rectTransform = ((Graphic)val2).rectTransform;
rectTransform.anchorMin = Vector2.zero;
rectTransform.anchorMax = Vector2.one;
rectTransform.offsetMin = new Vector2(2f, 2f);
rectTransform.offsetMax = new Vector2(-2f, -2f);
RectTransform val3 = CreateChild("Content", val.transform).AddComponent<RectTransform>();
val3.anchorMin = Vector2.zero;
val3.anchorMax = Vector2.one;
val3.offsetMin = new Vector2(9f, 9f);
val3.offsetMax = new Vector2(-9f, -9f);
DeckStatusRow[] array = new DeckStatusRow[rowCapacity];
for (int i = 0; i < rowCapacity; i++)
{
array[i] = BuildRow(val3, deck, list, list2, i);
}
return new DeckStatusPanelHandle(val, array, val2, list.ToArray(), list2.ToArray());
}
private static DeckStatusRow BuildRow(RectTransform parent, FFDataDeck deck, List<Image> tintedImages, List<TextMeshProUGUI> tintedTexts, int index)
{
//IL_0029: 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_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: 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_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_018e: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d5: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0209: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: Unknown result type (might be due to invalid IL or missing references)
//IL_0232: Unknown result type (might be due to invalid IL or missing references)
//IL_0254: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Unknown result type (might be due to invalid IL or missing references)
//IL_028b: Unknown result type (might be due to invalid IL or missing references)
//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Unknown result type (might be due to invalid IL or missing references)
//IL_0329: Unknown result type (might be due to invalid IL or missing references)
//IL_033e: Unknown result type (might be due to invalid IL or missing references)
//IL_0352: Unknown result type (might be due to invalid IL or missing references)
//IL_0374: Unknown result type (might be due to invalid IL or missing references)
GameObject val = CreateChild("Row" + index, (Transform)(object)parent);
RectTransform obj = val.AddComponent<RectTransform>();
obj.anchorMin = new Vector2(0f, 1f);
obj.anchorMax = new Vector2(1f, 1f);
obj.pivot = new Vector2(0f, 1f);
obj.anchoredPosition = new Vector2(0f, -36f * (float)index);
obj.sizeDelta = new Vector2(0f, 36f);
GameObject obj2 = CreateChild("Label", val.transform);
RectTransform obj3 = obj2.AddComponent<RectTransform>();
obj3.anchorMin = new Vector2(0f, 0.5f);
obj3.anchorMax = new Vector2(0f, 0.5f);
obj3.pivot = new Vector2(0f, 0.5f);
obj3.anchoredPosition = Vector2.zero;
obj3.sizeDelta = new Vector2(132f, 21f);
TextMeshProUGUI val2 = obj2.AddComponent<TextMeshProUGUI>();
SetupText(val2, deck, 21f, rightAligned: false);
tintedTexts.Add(val2);
GameObject val3 = CreateChild("Bar", val.transform);
RectTransform obj4 = val3.AddComponent<RectTransform>();
obj4.anchorMin = new Vector2(0f, 0.5f);
obj4.anchorMax = new Vector2(0f, 0.5f);
obj4.pivot = new Vector2(0f, 0.5f);
obj4.anchoredPosition = new Vector2(132f, 0f);
obj4.sizeDelta = new Vector2(136f, 13f);
Image val4 = CreateImage("Track", val3.transform, TrackColor);
RectTransform rectTransform = ((Graphic)val4).rectTransform;
rectTransform.anchorMin = Vector2.zero;
rectTransform.anchorMax = Vector2.one;
rectTransform.offsetMin = Vector2.zero;
rectTransform.offsetMax = Vector2.zero;
Image val5 = CreateImage("LowWarning", ((Component)val4).transform, Color.white);
RectTransform rectTransform2 = ((Graphic)val5).rectTransform;
rectTransform2.anchorMin = Vector2.zero;
rectTransform2.anchorMax = Vector2.one;
rectTransform2.offsetMin = new Vector2(-4f, -3f);
rectTransform2.offsetMax = new Vector2(4f, 3f);
((Component)val5).gameObject.SetActive(false);
Image val6 = CreateImage("Fill", ((Component)val4).transform, Color.white);
RectTransform rectTransform3 = ((Graphic)val6).rectTransform;
rectTransform3.anchorMin = new Vector2(0f, 0f);
rectTransform3.anchorMax = new Vector2(0f, 1f);
rectTransform3.pivot = new Vector2(0f, 0.5f);
rectTransform3.anchoredPosition = Vector2.zero;
rectTransform3.sizeDelta = Vector2.zero;
if ((Object)(object)deck != (Object)null)
{
DeckTint.BindImage(val6, deck, darken: false);
}
tintedImages.Add(val6);
GameObject obj5 = CreateChild("Value", val.transform);
RectTransform obj6 = obj5.AddComponent<RectTransform>();
obj6.anchorMin = new Vector2(0f, 0.5f);
obj6.anchorMax = new Vector2(0f, 0.5f);
obj6.pivot = new Vector2(1f, 0.5f);
obj6.anchoredPosition = new Vector2(336f, 0f);
obj6.sizeDelta = new Vector2(68f, 21f);
TextMeshProUGUI val7 = obj5.AddComponent<TextMeshProUGUI>();
SetupText(val7, deck, 21f, rightAligned: true);
((Graphic)val7).color = EmptyValueColor;
tintedTexts.Add(val7);
return new DeckStatusRow(val, val2, val7, val4, val5, val6, rectTransform3);
}
private static void SetupText(TextMeshProUGUI text, FFDataDeck deck, float targetHeight, bool rightAligned, bool bindTint = true)
{
//IL_0016: 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)
((Graphic)text).raycastTarget = false;
((TMP_Text)text).enableWordWrapping = false;
((TMP_Text)text).overflowMode = (TextOverflowModes)0;
((TMP_Text)text).margin = Vector4.zero;
((Graphic)text).color = Color.white;
DeckTextStyle.Apply(text, deck, targetHeight);
((TMP_Text)text).alignment = (TextAlignmentOptions)(rightAligned ? 4100 : 4097);
if (bindTint && (Object)(object)deck != (Object)null)
{
DeckTint.BindText(text, deck, darken: false);
}
}
private static Image CreateImage(string name, Transform parent, Color color)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
Image obj = CreateChild(name, parent).AddComponent<Image>();
obj.sprite = White();
obj.type = (Type)0;
((Graphic)obj).color = color;
((Graphic)obj).raycastTarget = false;
return obj;
}
private static GameObject CreateChild(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_0014: Expected O, but got Unknown
GameObject val = new GameObject(name);
val.transform.SetParent(parent, false);
return val;
}
private static Sprite White()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0028: 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_0066: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)whiteUnitSprite != (Object)null)
{
return whiteUnitSprite;
}
whiteUnitTexture = new Texture2D(1, 1, (TextureFormat)4, false);
whiteUnitTexture.SetPixel(0, 0, Color.white);
whiteUnitTexture.Apply(false, true);
whiteUnitSprite = Sprite.Create(whiteUnitTexture, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 100f);
return whiteUnitSprite;
}
public static void ReleaseSharedAssets()
{
try
{
if ((Object)(object)whiteUnitSprite != (Object)null)
{
Object.Destroy((Object)(object)whiteUnitSprite);
whiteUnitSprite = null;
}
if ((Object)(object)whiteUnitTexture != (Object)null)
{
Object.Destroy((Object)(object)whiteUnitTexture);
whiteUnitTexture = null;
}
}
catch
{
}
}
}
internal readonly struct DeckStatusPanelHandle
{
public GameObject Root { get; }
public DeckStatusRow[] Rows { get; }
private Image Background { get; }
private Image[] TintedImages { get; }
private TextMeshProUGUI[] TintedTexts { get; }
public bool IsValid
{
get
{
if ((Object)(object)Root != (Object)null && Rows != null)
{
return Rows.Length != 0;
}
return false;
}
}
public DeckStatusPanelHandle(GameObject root, DeckStatusRow[] rows, Image background, Image[] tintedImages, TextMeshProUGUI[] tintedTexts)
{
Root = root;
Rows = rows;
Background = background;
TintedImages = tintedImages;
TintedTexts = tintedTexts;
}
public void SetVisible(bool visible)
{
try
{
if ((Object)(object)Root != (Object)null && Root.activeSelf != visible)
{
Root.SetActive(visible);
}
}
catch
{
}
}
public void SetRow(int index, string label, float ratio, string valueText = null, bool lowWarning = false)
{
if (!IsValid || index < 0 || index >= Rows.Length)
{
return;
}
try
{
Rows[index].Set(label, ratio, valueText, lowWarning);
}
catch
{
}
}
public void SetBackgroundAlpha(float alpha)
{
//IL_0037: 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_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)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)Background != (Object)null)
{
bool flag = alpha > 0.001f;
if (((Behaviour)Background).enabled != flag)
{
((Behaviour)Background).enabled = flag;
}
Color color = ((Graphic)Background).color;
color.a = Mathf.Clamp01(alpha);
if (((Graphic)Background).color != color)
{
((Graphic)Background).color = color;
}
}
}
catch
{
}
}
public void SetRowVisible(int index, bool visible)
{
if (!IsValid || index < 0 || index >= Rows.Length)
{
return;
}
try
{
if (Rows[index].IsVisible != visible)
{
Rows[index].SetVisible(visible);
}
}
catch
{
}
}
public void ClearRows()
{
if (!IsValid)
{
return;
}
for (int i = 0; i < Rows.Length; i++)
{
try
{
if (Rows[i].IsVisible)
{
Rows[i].SetVisible(visible: false);
}
}
catch
{
}
}
}
public int ApplyVisibleLayout()
{
if (!IsValid)
{
return 0;
}
int num = 0;
for (int i = 0; i < Rows.Length; i++)
{
bool isVisible;
try
{
isVisible = Rows[i].IsVisible;
}
catch
{
continue;
}
if (isVisible)
{
try
{
Rows[i].SetVisualIndex(num);
}
catch
{
}
num++;
}
}
return Mathf.Max(1, num);
}
public bool RefreshFlavor(FFDataDeck deck, bool refreshTextStyle)
{
//IL_00a9: 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_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
if (!IsValid || !DeckTextStyle.TryResolveDeckColor(deck, out var color))
{
return false;
}
if (TintedTexts != null)
{
for (int i = 0; i < TintedTexts.Length; i++)
{
TextMeshProUGUI val = TintedTexts[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
try
{
if (refreshTextStyle)
{
DeckTextStyle.Apply(val, deck, 21f);
((TMP_Text)val).alignment = (TextAlignmentOptions)(string.Equals(((Object)((Component)val).gameObject).name, "Value", StringComparison.Ordinal) ? 4100 : 4097);
}
((Graphic)val).color = color;
}
catch
{
}
}
}
if (TintedImages != null)
{
for (int j = 0; j < TintedImages.Length; j++)
{
Image val2 = TintedImages[j];
try
{
if ((Object)(object)val2 != (Object)null && ((Graphic)val2).color != color)
{
((Graphic)val2).color = color;
}
}
catch
{
}
}
}
return true;
}
public void Destroy()
{
try
{
if ((Object)(object)Root != (Object)null)
{
Object.Destroy((Object)(object)Root);
}
}
catch
{
}
}
}
internal readonly struct DeckStatusRow
{
private readonly GameObject root;
private readonly TextMeshProUGUI label;
private readonly TextMeshProUGUI value;
private readonly Image track;
private readonly Image lowWarning;
private readonly Image fill;
private readonly RectTransform fillRect;
private readonly RectTransform rootRect;
public bool IsVisible
{
get
{
try
{
return (Object)(object)root != (Object)null && root.activeSelf;
}
catch
{
return false;
}
}
}
public DeckStatusRow(GameObject root, TextMeshProUGUI label, TextMeshProUGUI value, Image track, Image lowWarning, Image fill, RectTransform fillRect)
{
this.root = root;
rootRect = (((Object)(object)root != (Object)null) ? root.GetComponent<RectTransform>() : null);
this.label = label;
this.value = value;
this.track = track;
this.lowWarning = lowWarning;
this.fill = fill;
this.fillRect = fillRect;
}
public void SetVisible(bool visible)
{
try
{
if ((Object)(object)root != (Object)null && root.activeSelf != visible)
{
root.SetActive(visible);
}
}
catch
{
}
}
public void SetVisualIndex(int index)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
try
{
if ((Object)(object)rootRect != (Object)null)
{
rootRect.anchoredPosition = new Vector2(0f, -36f * (float)index);
}
}
catch
{
}
}
public void Set(string labelText, float ratio, string valueText, bool showLowWarning)
{
//IL_0074: 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_008b: 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_0108: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01af: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: 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)
//IL_014f: 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_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_017a: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: 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_019b: Unknown result type (might be due to invalid IL or missing references)
//IL_0284: 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_0289: Unknown result type (might be due to invalid IL or missing references)
//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
//IL_028d: Unknown result type (might be due to invalid IL or missing references)
//IL_0294: Unknown result type (might be due to invalid IL or missing references)
//IL_029b: Unknown result type (might be due to invalid IL or missing references)
//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)root != (Object)null && !root.activeSelf)
{
root.SetActive(true);
}
if ((Object)(object)label != (Object)null)
{
string text = labelText ?? string.Empty;
if (!string.Equals(((TMP_Text)label).text, text, StringComparison.Ordinal))
{
((TMP_Text)label).text = text;
}
}
if ((Object)(object)track != (Object)null)
{
if (((Graphic)track).color != DeckStatusPanel.TrackColor)
{
((Graphic)track).color = DeckStatusPanel.TrackColor;
}
if (!((Component)track).gameObject.activeSelf)
{
((Component)track).gameObject.SetActive(true);
}
}
if ((Object)(object)lowWarning != (Object)null && ((Component)lowWarning).gameObject.activeSelf)
{
((Component)lowWarning).gameObject.SetActive(false);
}
if ((Object)(object)fill != (Object)null)
{
Color val = (((Object)(object)label != (Object)null) ? ((Graphic)label).color : Color.white);
if (showLowWarning)
{
float num = (Mathf.Sin(Time.unscaledTime * 4.5f) + 1f) * 0.5f;
Color val2 = Color.Lerp(val, Color.black, 0.65f);
val2.a = Mathf.Clamp01(val.a * 0.28f);
Color val3 = Color.Lerp(val, val2, Mathf.Lerp(0.15f, 0.9f, num));
if (((Graphic)fill).color != val3)
{
((Graphic)fill).color = val3;
}
}
else if (((Graphic)fill).color != val)
{
((Graphic)fill).color = val;
}
if (!((Component)fill).gameObject.activeSelf)
{
((Component)fill).gameObject.SetActive(true);
}
}
if ((Object)(object)fillRect != (Object)null)
{
float num2 = 136f * Mathf.Clamp01(ratio);
fillRect.SetSizeWithCurrentAnchors((Axis)0, (num2 < 0.5f) ? 0f : num2);
}
if ((Object)(object)value != (Object)null)
{
bool num3 = !string.IsNullOrEmpty(valueText);
string text2 = (num3 ? valueText : string.Empty);
if (!string.Equals(((TMP_Text)value).text, text2, StringComparison.Ordinal))
{
((TMP_Text)value).text = text2;
}
Color val4 = (((Object)(object)label != (Object)null) ? ((Graphic)label).color : Color.white);
Color val5 = (Color)(num3 ? val4 : new Color(val4.r, val4.g, val4.b, 0f));
if (((Graphic)value).color != val5)
{
((Graphic)value).color = val5;
}
}
}
}
internal static class DeckTextStyle
{
public static void Apply(TextMeshProUGUI label, FFDataDeck deck, float targetHeight)
{
//IL_0065: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)label == (Object)null)
{
return;
}
TextMeshProUGUI val = TryGetStyleSource(deck);
if ((Object)(object)val == (Object)null)
{
((TMP_Text)label).fontSize = Mathf.Clamp(targetHeight, 10f, 24f);
((TMP_Text)label).alignment = (TextAlignmentOptions)257;
return;
}
try
{
((TMP_Text)label).font = ((TMP_Text)val).font;
if ((Object)(object)((TMP_Text)val).fontSharedMaterial != (Object)null)
{
((TMP_Text)label).fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial;
}
((TMP_Text)label).fontStyle = ((TMP_Text)val).fontStyle;
((TMP_Text)label).fontWeight = ((TMP_Text)val).fontWeight;
((TMP_Text)label).characterSpacing = ((TMP_Text)val).characterSpacing;
((TMP_Text)label).wordSpacing = ((TMP_Text)val).wordSpacing;
}
catch
{
((TMP_Text)label).fontSize = Mathf.Clamp(targetHeight, 10f, 24f);
((TMP_Text)label).alignment = (TextAlignmentOptions)257;
return;
}
float num = 40f;
if ((Object)(object)((TMP_Text)val).rectTransform != (Object)null)
{
num = Mathf.Max(1f, ((TMP_Text)val).rectTransform.sizeDelta.y);
}
((TMP_Text)label).fontSize = Mathf.Clamp(((TMP_Text)val).fontSize * (targetHeight / num), 10f, 24f);
((TMP_Text)label).alignment = (TextAlignmentOptions)257;
((TMP_Text)label).lineSpacing = 0f;
((TMP_Text)label).paragraphSpacing = 0f;
}
public static Color ResolveDeckColor(FFDataDeck deck, Color fallback)
{
//IL_001d: 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_0010: 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_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)
TextMeshProUGUI val = TryGetStyleSource(deck);
if ((Object)(object)val == (Object)null)
{
return fallback;
}
try
{
return ((Graphic)val).color;
}
catch
{
return fallback;
}
}
public static bool TryResolveDeckColor(FFDataDeck deck, out Color color)
{
//IL_0001: 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_0021: Unknown result type (might be due to invalid IL or missing references)
color = default(Color);
TextMeshProUGUI val = TryGetStyleSource(deck);
if ((Object)(object)val == (Object)null)
{
return false;
}
try
{
color = ((Graphic)val).color;
return true;
}
catch
{
return false;
}
}
private static TextMeshProUGUI TryGetStyleSource(FFDataDeck deck)
{
if ((Object)(object)deck == (Object)null)
{
return null;
}
TextMeshProUGUI[] array;
try
{
array = (TextMeshProUGUI[])(object)new TextMeshProUGUI[4] { deck.gameTime, deck.characterName, deck.credits, deck.flavorText };
}
catch
{
return null;
}
foreach (TextMeshProUGUI val in array)
{
if (IsUsable(val))
{
return val;
}
}
return null;
}
private static bool IsUsable(TextMeshProUGUI text)
{
if ((Object)(object)text == (Object)null)
{
return false;
}
try
{
_ = ((Component)text).gameObject;
_ = ((TMP_Text)text).rectTransform;
_ = ((TMP_Text)text).fontSize;
return true;
}
catch
{
return false;
}
}
}
internal static class DeckTint
{
public static FFDataDeckUIColorer BindImage(Image image, FFDataDeck deck, bool darken)
{
//IL_000d: 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_001f: 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_001c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)image == (Object)null)
{
return null;
}
Color val = DeckTextStyle.ResolveDeckColor(deck, ((Graphic)image).color);
((Graphic)image).color = (darken ? Darken(val) : val);
return null;
}
public static FFDataDeckUIColorer BindText(TextMeshProUGUI text, FFDataDeck deck, bool darken)
{
//IL_000d: 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_001f: 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_001c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)text == (Object)null)
{
return null;
}
Color val = DeckTextStyle.ResolveDeckColor(deck, ((Graphic)text).color);
((Graphic)text).color = (darken ? Darken(val) : val);
return null;
}
private static Color Darken(Color color)
{
//IL_0000: 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_0018: 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_002a: Unknown result type (might be due to invalid IL or missing references)
return new Color(color.r * 0.6f, color.g * 0.6f, color.b * 0.6f, color.a);
}
}
}