Decompiled source of ReadyViking v0.1.0

ReadyViking.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using ReadyViking.Config;
using ReadyViking.Input;
using ReadyViking.Models;
using ReadyViking.Overlay;
using ReadyViking.Runtime;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ReadyViking.Config
{
	internal sealed class ReadyVikingConfig
	{
		public ConfigEntry<KeyboardShortcut> ToggleOverlay { get; private set; }

		public ConfigEntry<float> AutoHideSeconds { get; private set; }

		public ConfigEntry<float> WeaponDurabilityWarningPercent { get; private set; }

		public ConfigEntry<float> OverlayPositionX { get; private set; }

		public ConfigEntry<float> OverlayPositionY { get; private set; }

		public ReadyVikingConfig(ConfigFile config)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			ToggleOverlay = config.Bind<KeyboardShortcut>("General", "ToggleOverlay", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Toggle the ReadyViking test overlay.");
			AutoHideSeconds = config.Bind<float>("General", "AutoHideSeconds", 6f, "Seconds until the overlay hides itself after opening.");
			WeaponDurabilityWarningPercent = config.Bind<float>("General", "WeaponDurabilityWarningPercent", 25f, new ConfigDescription("Weapon durability percentage at or below which the overlay shows a warning.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			OverlayPositionX = config.Bind<float>("Overlay", "OverlayPositionX", 24f, "Horizontal screen position of the ReadyViking overlay.");
			OverlayPositionY = config.Bind<float>("Overlay", "OverlayPositionY", 170f, "Vertical screen position of the ReadyViking overlay.");
		}
	}
}
namespace ReadyViking.Input
{
	internal sealed class ReadyVikingInputController
	{
		private readonly ConfigEntry<KeyboardShortcut> _toggleOverlay;

		public ReadyVikingInputController(ConfigEntry<KeyboardShortcut> toggleOverlay)
		{
			_toggleOverlay = toggleOverlay;
		}

		public bool TogglePressed()
		{
			//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)
			KeyboardShortcut value = _toggleOverlay.Value;
			return ((KeyboardShortcut)(ref value)).IsDown();
		}
	}
}
namespace ReadyViking.Models
{
	internal sealed class ActiveMealSnapshot
	{
		public string Name { get; private set; }

		public float RemainingSeconds { get; private set; }

		public ActiveMealSnapshot(string name, float remainingSeconds)
		{
			Name = name;
			RemainingSeconds = remainingSeconds;
		}
	}
	internal sealed class ActiveMealsSnapshot
	{
		public CheckState State { get; private set; }

		public int ActiveMealCount { get; private set; }

		public IReadOnlyList<ActiveMealSnapshot> Meals { get; private set; }

		public ActiveMealsSnapshot(CheckState state, int activeMealCount, IReadOnlyList<ActiveMealSnapshot> meals)
		{
			State = state;
			ActiveMealCount = activeMealCount;
			Meals = meals;
		}
	}
	internal sealed class AmmoSnapshot
	{
		public CheckState State { get; private set; }

		public bool RequiresAmmo { get; private set; }

		public string AmmoType { get; private set; }

		public int AvailableAmmo { get; private set; }

		public AmmoSnapshot(CheckState state, bool requiresAmmo, string ammoType, int availableAmmo)
		{
			State = state;
			RequiresAmmo = requiresAmmo;
			AmmoType = ammoType;
			AvailableAmmo = availableAmmo;
		}
	}
	internal sealed class CheckResult
	{
		public string Title { get; private set; }

		public CheckState State { get; private set; }

		public string Detail { get; private set; }

		public CheckResult(string title, CheckState state, string detail)
		{
			Title = title;
			State = state;
			Detail = detail;
		}
	}
	internal enum CheckState
	{
		Ready,
		Warning,
		Missing,
		Unknown,
		NotApplicable
	}
	internal sealed class InventorySnapshot
	{
		public CheckState SlotsState { get; private set; }

		public int FreeSlots { get; private set; }

		public int TotalSlots { get; private set; }

		public CheckState WeightState { get; private set; }

		public float CurrentWeight { get; private set; }

		public float MaxWeight { get; private set; }

		public InventorySnapshot(CheckState slotsState, int freeSlots, int totalSlots, CheckState weightState, float currentWeight, float maxWeight)
		{
			SlotsState = slotsState;
			FreeSlots = freeSlots;
			TotalSlots = totalSlots;
			WeightState = weightState;
			CurrentWeight = currentWeight;
			MaxWeight = maxWeight;
		}
	}
	internal sealed class ReadinessReport
	{
		public string Headline { get; private set; }

		public IReadOnlyList<CheckResult> Checks { get; private set; }

		public ReadinessReport(string headline, IReadOnlyList<CheckResult> checks)
		{
			Headline = headline;
			Checks = checks;
		}
	}
	internal sealed class ReadyVikingSnapshot
	{
		public SnapshotStatus LocalPlayerStatus { get; private set; }

		public ActiveMealsSnapshot ActiveMeals { get; private set; }

		public WeaponSnapshot Weapon { get; private set; }

		public RestedSnapshot Rested { get; private set; }

		public AmmoSnapshot Ammo { get; private set; }

		public InventorySnapshot Inventory { get; private set; }

		public bool LocalPlayerAvailable => LocalPlayerStatus == SnapshotStatus.Available;

		public ReadyVikingSnapshot(SnapshotStatus localPlayerStatus, ActiveMealsSnapshot activeMeals, WeaponSnapshot weapon, RestedSnapshot rested, AmmoSnapshot ammo, InventorySnapshot inventory)
		{
			LocalPlayerStatus = localPlayerStatus;
			ActiveMeals = activeMeals;
			Weapon = weapon;
			Rested = rested;
			Ammo = ammo;
			Inventory = inventory;
		}
	}
	internal sealed class RestedSnapshot
	{
		public CheckState State { get; private set; }

		public bool IsRested { get; private set; }

		public float RemainingSeconds { get; private set; }

		public RestedSnapshot(CheckState state, bool isRested, float remainingSeconds)
		{
			State = state;
			IsRested = isRested;
			RemainingSeconds = remainingSeconds;
		}
	}
	internal enum SnapshotStatus
	{
		Available,
		Unknown,
		Unavailable
	}
	internal sealed class WeaponSnapshot
	{
		public CheckState State { get; private set; }

		public string Name { get; private set; }

		public float CurrentDurability { get; private set; }

		public float MaxDurability { get; private set; }

		public float DurabilityPercent { get; private set; }

		public WeaponSnapshot(CheckState state, string name, float currentDurability, float maxDurability, float durabilityPercent)
		{
			State = state;
			Name = name;
			CurrentDurability = currentDurability;
			MaxDurability = maxDurability;
			DurabilityPercent = durabilityPercent;
		}
	}
}
namespace ReadyViking.Overlay
{
	internal sealed class ReadyVikingOverlayView
	{
		private const float PanelWidth = 360f;

		private const float PanelHeight = 220f;

		private GUIStyle _titleStyle;

		private GUIStyle _rowStyle;

		private GUIStyle _detailStyle;

		private GUIStyle _panelStyle;

		public void Draw(ReadinessReport report, float positionX, float positionY)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			EnsureStyles();
			Rect val = CreateClampedPanelRect(positionX, positionY);
			GUILayout.BeginArea(val, _panelStyle);
			GUILayout.Label(report.Headline, _titleStyle, Array.Empty<GUILayoutOption>());
			foreach (CheckResult check in report.Checks)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				GUILayout.Label(GetPrefix(check.State), _rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) });
				GUILayout.Label(check.Title, _rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
				GUILayout.Label(check.Detail, _detailStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndHorizontal();
			}
			GUILayout.EndArea();
		}

		private static Rect CreateClampedPanelRect(float positionX, float positionY)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0f, (float)Screen.width - 360f);
			float num2 = Mathf.Max(0f, (float)Screen.height - 220f);
			float num3 = Mathf.Clamp(positionX, 0f, num);
			float num4 = Mathf.Clamp(positionY, 0f, num2);
			return new Rect(num3, num4, 360f, 220f);
		}

		private void EnsureStyles()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			if (_panelStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.box);
				val.padding = new RectOffset(14, 14, 12, 12);
				val.margin = new RectOffset(0, 0, 0, 0);
				_panelStyle = val;
				val = new GUIStyle(GUI.skin.label);
				val.fontSize = 18;
				val.fontStyle = (FontStyle)1;
				val.richText = true;
				val.alignment = (TextAnchor)3;
				_titleStyle = val;
				val = new GUIStyle(GUI.skin.label);
				val.fontSize = 13;
				val.richText = true;
				val.alignment = (TextAnchor)3;
				_rowStyle = val;
				val = new GUIStyle(GUI.skin.label);
				val.fontSize = 13;
				val.richText = true;
				val.alignment = (TextAnchor)3;
				_detailStyle = val;
			}
		}

		private static string GetPrefix(CheckState state)
		{
			return state switch
			{
				CheckState.Ready => "<color=#8BC34A>OK</color>", 
				CheckState.Warning => "<color=#FFC107>WARN</color>", 
				CheckState.Missing => "<color=#EF5350>MISS</color>", 
				CheckState.Unknown => "<color=#B0BEC5>UNK</color>", 
				CheckState.NotApplicable => "<color=#90A4AE>N/A</color>", 
				_ => "<color=#B0BEC5>UNK</color>", 
			};
		}
	}
}
namespace ReadyViking
{
	[BepInPlugin("com.goblinstudio.readyviking", "ReadyViking", "0.1.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private ReadyVikingConfig _config;

		private ReadyVikingInputController _input;

		private ReadyVikingOverlayView _overlayView;

		private ReadyVikingSnapshotCollector _snapshotCollector;

		private ReadinessReport _currentReport;

		private bool _isVisible;

		private float _openedAt;

		private void Awake()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			_config = new ReadyVikingConfig(((BaseUnityPlugin)this).Config);
			_input = new ReadyVikingInputController(_config.ToggleOverlay);
			_overlayView = new ReadyVikingOverlayView();
			_snapshotCollector = new ReadyVikingSnapshotCollector();
			_currentReport = StaticTestReportFactory.Create();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[ReadyViking] loaded v0.1.0");
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[ReadyViking] Hotkey: " + _config.ToggleOverlay.Value));
		}

		private void Update()
		{
			if (_input != null && _config != null)
			{
				if (_input.TogglePressed())
				{
					ToggleOverlay();
				}
				if (_isVisible && Time.realtimeSinceStartup - _openedAt >= Mathf.Max(0.25f, _config.AutoHideSeconds.Value))
				{
					_isVisible = false;
				}
			}
		}

		private void OnGUI()
		{
			if (_isVisible && _overlayView != null && _currentReport != null)
			{
				_overlayView.Draw(_currentReport, _config.OverlayPositionX.Value, _config.OverlayPositionY.Value);
			}
		}

		private void ToggleOverlay()
		{
			_isVisible = !_isVisible;
			_openedAt = Time.realtimeSinceStartup;
			if (_isVisible)
			{
				ReadyVikingSnapshot readyVikingSnapshot = _snapshotCollector.Collect();
				_currentReport = StaticTestReportFactory.Create(readyVikingSnapshot.ActiveMeals, readyVikingSnapshot.Weapon, _config.WeaponDurabilityWarningPercent.Value, readyVikingSnapshot.Rested, readyVikingSnapshot.Ammo, readyVikingSnapshot.Inventory);
				string text = ((readyVikingSnapshot.LocalPlayerStatus != SnapshotStatus.Available) ? "Unavailable" : "Available");
				string text2 = ((!readyVikingSnapshot.LocalPlayerAvailable) ? "no" : "yes");
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[ReadyViking] Snapshot status: " + text + "; local player available: " + text2));
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("[ReadyViking] Weapon snapshot: state=", readyVikingSnapshot.Weapon.State, "; name=", readyVikingSnapshot.Weapon.Name, "; current=", readyVikingSnapshot.Weapon.CurrentDurability, "; max=", readyVikingSnapshot.Weapon.MaxDurability, "; percent=", readyVikingSnapshot.Weapon.DurabilityPercent));
				string text3 = ((!readyVikingSnapshot.Rested.IsRested) ? "no" : "yes");
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("[ReadyViking] Rested snapshot: state=", readyVikingSnapshot.Rested.State, "; rested=", text3, "; remaining=", readyVikingSnapshot.Rested.RemainingSeconds));
				string text4 = ((!readyVikingSnapshot.Ammo.RequiresAmmo) ? "no" : "yes");
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("[ReadyViking] Ammo snapshot: state=", readyVikingSnapshot.Ammo.State, "; required=", text4, "; type=", readyVikingSnapshot.Ammo.AmmoType, "; available=", readyVikingSnapshot.Ammo.AvailableAmmo));
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("[ReadyViking] Inventory snapshot: slotsState=", readyVikingSnapshot.Inventory.SlotsState, "; free=", readyVikingSnapshot.Inventory.FreeSlots, "; total=", readyVikingSnapshot.Inventory.TotalSlots, "; weightState=", readyVikingSnapshot.Inventory.WeightState, "; current=", readyVikingSnapshot.Inventory.CurrentWeight, "; max=", readyVikingSnapshot.Inventory.MaxWeight));
			}
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "com.goblinstudio.readyviking";

		public const string Name = "ReadyViking";

		public const string Version = "0.1.0";
	}
}
namespace ReadyViking.Runtime
{
	internal sealed class ReadyVikingSnapshotCollector
	{
		public ReadyVikingSnapshot Collect()
		{
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0655: Unknown result type (might be due to invalid IL or missing references)
			//IL_074c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0751: Unknown result type (might be due to invalid IL or missing references)
			//IL_0753: Unknown result type (might be due to invalid IL or missing references)
			//IL_0757: Invalid comparison between Unknown and I4
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0760: Invalid comparison between Unknown and I4
			//IL_0765: Unknown result type (might be due to invalid IL or missing references)
			//IL_0768: Invalid comparison between Unknown and I4
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return new ReadyVikingSnapshot(SnapshotStatus.Unavailable, new ActiveMealsSnapshot(CheckState.NotApplicable, 0, new List<ActiveMealSnapshot>()), new WeaponSnapshot(CheckState.NotApplicable, string.Empty, 0f, 0f, 0f), new RestedSnapshot(CheckState.NotApplicable, isRested: false, 0f), new AmmoSnapshot(CheckState.NotApplicable, requiresAmmo: false, string.Empty, 0), new InventorySnapshot(CheckState.NotApplicable, 0, 0, CheckState.NotApplicable, 0f, 0f));
			}
			Inventory val = null;
			bool flag = false;
			try
			{
				val = ((Humanoid)localPlayer).GetInventory();
				flag = true;
			}
			catch (Exception)
			{
				val = null;
			}
			InventorySnapshot inventory;
			if (!flag || val == null)
			{
				inventory = new InventorySnapshot(CheckState.Unknown, 0, 0, CheckState.Unknown, 0f, 0f);
			}
			else
			{
				int num = 0;
				int num2 = 0;
				CheckState slotsState;
				try
				{
					int emptySlots = val.GetEmptySlots();
					int width = val.GetWidth();
					int height = val.GetHeight();
					long num3 = (long)width * (long)height;
					if (width < 0 || height < 0 || num3 < 0 || num3 > int.MaxValue || emptySlots < 0 || emptySlots > num3)
					{
						throw new InvalidOperationException("Invalid inventory slot data");
					}
					slotsState = CheckState.Ready;
					num = emptySlots;
					num2 = (int)num3;
				}
				catch (Exception)
				{
					slotsState = CheckState.Unknown;
					num = 0;
					num2 = 0;
				}
				float num4 = 0f;
				float num5 = 0f;
				CheckState weightState;
				try
				{
					float totalWeight = val.GetTotalWeight();
					float maxCarryWeight = localPlayer.GetMaxCarryWeight();
					if (float.IsNaN(totalWeight) || float.IsInfinity(totalWeight) || totalWeight < 0f || float.IsNaN(maxCarryWeight) || float.IsInfinity(maxCarryWeight) || maxCarryWeight <= 0f)
					{
						throw new InvalidOperationException("Invalid inventory weight data");
					}
					weightState = CheckState.Ready;
					num4 = totalWeight;
					num5 = maxCarryWeight;
				}
				catch (Exception)
				{
					weightState = CheckState.Unknown;
					num4 = 0f;
					num5 = 0f;
				}
				inventory = new InventorySnapshot(slotsState, num, num2, weightState, num4, num5);
			}
			ActiveMealsSnapshot activeMeals;
			try
			{
				List<Food> foods = localPlayer.GetFoods();
				if (foods == null)
				{
					activeMeals = new ActiveMealsSnapshot(CheckState.Unknown, 0, new List<ActiveMealSnapshot>());
				}
				else
				{
					List<ActiveMealSnapshot> list = new List<ActiveMealSnapshot>(foods.Count);
					bool flag2 = true;
					foreach (Food item in foods)
					{
						if (item == null || string.IsNullOrWhiteSpace(item.m_name) || float.IsNaN(item.m_time) || float.IsInfinity(item.m_time) || item.m_time < 0f)
						{
							flag2 = false;
							break;
						}
						list.Add(new ActiveMealSnapshot(item.m_name, item.m_time));
					}
					if (!flag2)
					{
						activeMeals = new ActiveMealsSnapshot(CheckState.Unknown, 0, new List<ActiveMealSnapshot>());
					}
					else
					{
						CheckState state = ((list.Count == 0) ? CheckState.Missing : ((list.Count < 3) ? CheckState.Warning : CheckState.Ready));
						activeMeals = new ActiveMealsSnapshot(state, list.Count, list);
					}
				}
			}
			catch (Exception)
			{
				activeMeals = new ActiveMealsSnapshot(CheckState.Unknown, 0, new List<ActiveMealSnapshot>());
			}
			ItemData val2 = null;
			SharedData val3 = null;
			bool flag3 = false;
			bool flag4 = false;
			bool flag5 = false;
			WeaponSnapshot weapon;
			try
			{
				val2 = ((Humanoid)localPlayer).GetCurrentWeapon();
				flag3 = true;
				if (val2 == null)
				{
					weapon = new WeaponSnapshot(CheckState.NotApplicable, string.Empty, 0f, 0f, 0f);
				}
				else
				{
					val3 = val2.m_shared;
					if (val3 == null)
					{
						weapon = new WeaponSnapshot(CheckState.Unknown, string.Empty, 0f, 0f, 0f);
					}
					else if (string.IsNullOrWhiteSpace(val3.m_name))
					{
						weapon = new WeaponSnapshot(CheckState.Unknown, string.Empty, 0f, 0f, 0f);
					}
					else
					{
						flag5 = val2.IsWeapon();
						flag4 = true;
						if (!flag5)
						{
							weapon = (((int)val3.m_itemType != 0) ? new WeaponSnapshot(CheckState.Unknown, val3.m_name, 0f, 0f, 0f) : new WeaponSnapshot(CheckState.NotApplicable, val3.m_name, 0f, 0f, 0f));
						}
						else if (!val3.m_useDurability)
						{
							weapon = new WeaponSnapshot(CheckState.NotApplicable, val3.m_name, 0f, 0f, 0f);
						}
						else
						{
							float durability = val2.m_durability;
							float maxDurability = val2.GetMaxDurability();
							if (float.IsNaN(durability) || float.IsInfinity(durability) || durability < 0f || float.IsNaN(maxDurability) || float.IsInfinity(maxDurability) || maxDurability <= 0f || durability > maxDurability)
							{
								weapon = new WeaponSnapshot(CheckState.Unknown, val3.m_name, 0f, 0f, 0f);
							}
							else
							{
								float durabilityPercent = Mathf.Clamp(durability / maxDurability * 100f, 0f, 100f);
								weapon = new WeaponSnapshot(CheckState.Ready, val3.m_name, durability, maxDurability, durabilityPercent);
							}
						}
					}
				}
			}
			catch (Exception)
			{
				weapon = new WeaponSnapshot(CheckState.Unknown, string.Empty, 0f, 0f, 0f);
			}
			RestedSnapshot rested;
			try
			{
				SEMan sEMan = ((Character)localPlayer).GetSEMan();
				if (sEMan == null)
				{
					rested = new RestedSnapshot(CheckState.Unknown, isRested: false, 0f);
				}
				else
				{
					StatusEffect statusEffect = sEMan.GetStatusEffect(SEMan.s_statusEffectRested);
					if ((Object)(object)statusEffect == (Object)null)
					{
						rested = new RestedSnapshot(CheckState.Missing, isRested: false, 0f);
					}
					else
					{
						float remaningTime = statusEffect.GetRemaningTime();
						rested = ((!float.IsNaN(remaningTime) && !float.IsInfinity(remaningTime) && !(remaningTime <= 0f)) ? new RestedSnapshot(CheckState.Ready, isRested: true, remaningTime) : new RestedSnapshot(CheckState.Unknown, isRested: false, 0f));
					}
				}
			}
			catch (Exception)
			{
				rested = new RestedSnapshot(CheckState.Unknown, isRested: false, 0f);
			}
			string text = string.Empty;
			bool requiresAmmo = false;
			AmmoSnapshot ammo;
			try
			{
				if (!flag3)
				{
					ammo = new AmmoSnapshot(CheckState.Unknown, requiresAmmo: false, string.Empty, 0);
				}
				else if (val2 == null)
				{
					ammo = new AmmoSnapshot(CheckState.NotApplicable, requiresAmmo: false, string.Empty, 0);
				}
				else if (val3 == null || !flag4)
				{
					ammo = new AmmoSnapshot(CheckState.Unknown, requiresAmmo: false, string.Empty, 0);
				}
				else if (!flag5)
				{
					ammo = (((int)val3.m_itemType != 0) ? new AmmoSnapshot(CheckState.Unknown, requiresAmmo: false, string.Empty, 0) : new AmmoSnapshot(CheckState.NotApplicable, requiresAmmo: false, string.Empty, 0));
				}
				else
				{
					text = val3.m_ammoType;
					if (string.IsNullOrWhiteSpace(text))
					{
						ammo = new AmmoSnapshot(CheckState.NotApplicable, requiresAmmo: false, string.Empty, 0);
					}
					else
					{
						requiresAmmo = true;
						if (!flag || val == null)
						{
							ammo = new AmmoSnapshot(CheckState.Unknown, requiresAmmo: true, text, 0);
						}
						else
						{
							List<ItemData> allItems = val.GetAllItems();
							if (allItems == null)
							{
								ammo = new AmmoSnapshot(CheckState.Unknown, requiresAmmo: true, text, 0);
							}
							else
							{
								long num6 = 0L;
								bool flag6 = false;
								foreach (ItemData item2 in allItems)
								{
									if (item2 == null || item2.m_shared == null)
									{
										flag6 = true;
										break;
									}
									if (!string.Equals(item2.m_shared.m_ammoType, text, StringComparison.Ordinal))
									{
										continue;
									}
									ItemType itemType = item2.m_shared.m_itemType;
									if ((int)itemType != 9 && (int)itemType != 23 && (int)itemType != 2)
									{
										if (item2.IsWeapon())
										{
											continue;
										}
										flag6 = true;
										break;
									}
									if (item2.m_stack <= 0)
									{
										flag6 = true;
										break;
									}
									num6 += item2.m_stack;
									if (num6 <= int.MaxValue)
									{
										continue;
									}
									flag6 = true;
									break;
								}
								ammo = (flag6 ? new AmmoSnapshot(CheckState.Unknown, requiresAmmo: true, text, 0) : ((num6 <= 0) ? new AmmoSnapshot(CheckState.Missing, requiresAmmo: true, text, 0) : new AmmoSnapshot(CheckState.Ready, requiresAmmo: true, text, (int)num6)));
							}
						}
					}
				}
			}
			catch (Exception)
			{
				ammo = new AmmoSnapshot(CheckState.Unknown, requiresAmmo, text, 0);
			}
			return new ReadyVikingSnapshot(SnapshotStatus.Available, activeMeals, weapon, rested, ammo, inventory);
		}
	}
	internal static class StaticTestReportFactory
	{
		public static ReadinessReport Create()
		{
			return CreateReport(new CheckResult("Meals", CheckState.Ready, "Three active meals"));
		}

		public static ReadinessReport Create(ActiveMealsSnapshot activeMeals, WeaponSnapshot weapon, float weaponDurabilityWarningPercent, RestedSnapshot rested, AmmoSnapshot ammo, InventorySnapshot inventory)
		{
			return CreateReport(new CheckResult(string.Empty, activeMeals.State, CreateActiveMealsDetail(activeMeals)), CreateWeaponCheck(weapon, weaponDurabilityWarningPercent), CreateRestedCheck(rested), CreateAmmoCheck(ammo), CreateInventoryCheck(inventory));
		}

		private static ReadinessReport CreateReport(CheckResult mealsCheck, CheckResult weaponCheck = null, CheckResult restedCheck = null, CheckResult ammoCheck = null, CheckResult inventoryCheck = null)
		{
			if (weaponCheck == null)
			{
				weaponCheck = new CheckResult("Weapon", CheckState.Warning, "Sword durability: 28%");
			}
			if (restedCheck == null)
			{
				restedCheck = new CheckResult("Rested", CheckState.Ready, "14 min");
			}
			if (ammoCheck == null)
			{
				ammoCheck = new CheckResult("Ammo", CheckState.Missing, "No matching ammunition");
			}
			if (inventoryCheck == null)
			{
				inventoryCheck = new CheckResult("Inventory", CheckState.Unknown, "Inventory status unknown");
			}
			return new ReadinessReport("READY TO LEAVE?", new List<CheckResult> { mealsCheck, restedCheck, weaponCheck, ammoCheck, inventoryCheck });
		}

		private static string CreateActiveMealsDetail(ActiveMealsSnapshot activeMeals)
		{
			switch (activeMeals.State)
			{
			case CheckState.Ready:
			case CheckState.Warning:
			case CheckState.Missing:
				return "Active meals: " + activeMeals.ActiveMealCount;
			case CheckState.NotApplicable:
				return "Active meals unavailable";
			default:
				return "Active meals unknown";
			}
		}

		private static CheckResult CreateRestedCheck(RestedSnapshot rested)
		{
			if (rested == null)
			{
				return new CheckResult(string.Empty, CheckState.Unknown, "Rested status unknown");
			}
			switch (rested.State)
			{
			case CheckState.Ready:
			{
				if (!rested.IsRested || float.IsNaN(rested.RemainingSeconds) || float.IsInfinity(rested.RemainingSeconds) || rested.RemainingSeconds <= 0f)
				{
					return new CheckResult(string.Empty, CheckState.Unknown, "Rested status unknown");
				}
				int num = Mathf.Max(1, Mathf.FloorToInt(rested.RemainingSeconds / 60f));
				return new CheckResult(string.Empty, CheckState.Ready, "Rested: " + num + " min");
			}
			case CheckState.Missing:
				return new CheckResult(string.Empty, CheckState.Missing, "Rested not active");
			case CheckState.NotApplicable:
				return new CheckResult(string.Empty, CheckState.NotApplicable, "Rested unavailable");
			default:
				return new CheckResult(string.Empty, CheckState.Unknown, "Rested status unknown");
			}
		}

		private static CheckResult CreateAmmoCheck(AmmoSnapshot ammo)
		{
			if (ammo == null)
			{
				return new CheckResult(string.Empty, CheckState.Unknown, "Ammo status unknown");
			}
			switch (ammo.State)
			{
			case CheckState.Ready:
				if (!ammo.RequiresAmmo || string.IsNullOrWhiteSpace(ammo.AmmoType) || ammo.AvailableAmmo <= 0)
				{
					return new CheckResult(string.Empty, CheckState.Unknown, "Ammo status unknown");
				}
				return new CheckResult(string.Empty, CheckState.Ready, "Ammo: " + ammo.AvailableAmmo);
			case CheckState.Missing:
				if (!ammo.RequiresAmmo || string.IsNullOrWhiteSpace(ammo.AmmoType) || ammo.AvailableAmmo != 0)
				{
					return new CheckResult(string.Empty, CheckState.Unknown, "Ammo status unknown");
				}
				return new CheckResult(string.Empty, CheckState.Missing, "Ammo: none");
			case CheckState.NotApplicable:
				if (ammo.RequiresAmmo || !string.IsNullOrWhiteSpace(ammo.AmmoType) || ammo.AvailableAmmo != 0)
				{
					return new CheckResult(string.Empty, CheckState.Unknown, "Ammo status unknown");
				}
				return new CheckResult(string.Empty, CheckState.NotApplicable, "Ammo not applicable");
			default:
				return new CheckResult(string.Empty, CheckState.Unknown, "Ammo status unknown");
			}
		}

		private static CheckResult CreateInventoryCheck(InventorySnapshot inventory)
		{
			if (inventory == null)
			{
				return new CheckResult(string.Empty, CheckState.Unknown, "Inventory status unknown");
			}
			bool flag = inventory.SlotsState == CheckState.Ready && inventory.FreeSlots >= 0 && inventory.TotalSlots >= 0 && inventory.FreeSlots <= inventory.TotalSlots;
			bool flag2 = inventory.WeightState == CheckState.Ready && !float.IsNaN(inventory.CurrentWeight) && !float.IsInfinity(inventory.CurrentWeight) && inventory.CurrentWeight >= 0f && !float.IsNaN(inventory.MaxWeight) && !float.IsInfinity(inventory.MaxWeight) && inventory.MaxWeight > 0f;
			bool flag3 = inventory.SlotsState == CheckState.NotApplicable && inventory.FreeSlots == 0 && inventory.TotalSlots == 0;
			bool flag4 = inventory.WeightState == CheckState.NotApplicable && inventory.CurrentWeight == 0f && inventory.MaxWeight == 0f;
			bool flag5 = inventory.SlotsState == CheckState.Unknown && inventory.FreeSlots == 0 && inventory.TotalSlots == 0;
			bool flag6 = inventory.WeightState == CheckState.Unknown && inventory.CurrentWeight == 0f && inventory.MaxWeight == 0f;
			if (flag && flag2)
			{
				CheckState state = ((inventory.FreeSlots == 0 || inventory.CurrentWeight >= inventory.MaxWeight) ? CheckState.Warning : CheckState.Ready);
				return new CheckResult(string.Empty, state, "Inventory: " + inventory.FreeSlots + " free | " + FormatWeight(inventory.CurrentWeight) + "/" + FormatWeight(inventory.MaxWeight));
			}
			if (flag3 && flag4)
			{
				return new CheckResult(string.Empty, CheckState.NotApplicable, "Inventory unavailable");
			}
			if (flag && flag6)
			{
				return new CheckResult(string.Empty, CheckState.Unknown, "Inventory: " + inventory.FreeSlots + " free | weight unknown");
			}
			if (flag2 && flag5)
			{
				return new CheckResult(string.Empty, CheckState.Unknown, "Inventory: slots unknown | " + FormatWeight(inventory.CurrentWeight) + "/" + FormatWeight(inventory.MaxWeight));
			}
			return new CheckResult(string.Empty, CheckState.Unknown, "Inventory status unknown");
		}

		private static string FormatWeight(float value)
		{
			return value.ToString("0.#", CultureInfo.CurrentCulture);
		}

		private static CheckResult CreateWeaponCheck(WeaponSnapshot weapon, float warningPercent)
		{
			if (weapon == null)
			{
				return new CheckResult(string.Empty, CheckState.Unknown, "Weapon status unknown");
			}
			string displayName = GetDisplayName(weapon.Name);
			switch (weapon.State)
			{
			case CheckState.Ready:
			{
				if (string.IsNullOrWhiteSpace(displayName))
				{
					return new CheckResult(string.Empty, CheckState.Unknown, "Weapon status unknown");
				}
				float num = Mathf.Clamp(weapon.DurabilityPercent, 0f, 100f);
				int num2 = Mathf.RoundToInt(num);
				CheckState state = ((num <= Mathf.Clamp(warningPercent, 0f, 100f)) ? CheckState.Warning : CheckState.Ready);
				return new CheckResult(string.Empty, state, displayName + ": " + num2 + "%");
			}
			case CheckState.NotApplicable:
				if (string.IsNullOrWhiteSpace(displayName) || IsUnarmedName(weapon.Name))
				{
					return new CheckResult(string.Empty, CheckState.NotApplicable, "No weapon equipped");
				}
				return new CheckResult(string.Empty, CheckState.NotApplicable, displayName + ": no durability");
			case CheckState.Unknown:
				if (string.IsNullOrWhiteSpace(displayName))
				{
					return new CheckResult(string.Empty, CheckState.Unknown, "Weapon status unknown");
				}
				return new CheckResult(string.Empty, CheckState.Unknown, displayName + ": durability unknown");
			default:
				return new CheckResult(string.Empty, CheckState.Unknown, "Weapon status unknown");
			}
		}

		private static string GetDisplayName(string copiedName)
		{
			if (string.IsNullOrWhiteSpace(copiedName))
			{
				return string.Empty;
			}
			if (!copiedName.StartsWith("$"))
			{
				return copiedName;
			}
			try
			{
				if (Localization.instance != null)
				{
					string text = Localization.instance.Localize(copiedName);
					if (!string.IsNullOrWhiteSpace(text) && !text.StartsWith("$"))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			return copiedName;
		}

		private static bool IsUnarmedName(string copiedName)
		{
			return string.Equals(copiedName, "Unarmed", StringComparison.OrdinalIgnoreCase);
		}
	}
}