Decompiled source of BeginnerBuilds v0.6.3

plugins/BeginnerBuilds/BeginnerBuilds.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using EntityStates;
using HG;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Rewired;
using RoR2;
using RoR2.Skills;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BeginnerBuilds
{
	public sealed class SkillEvidence
	{
		public string Slot;

		public string Name;

		public string Description;

		public string InternalName;

		public string Source;

		public string CodeParameters;

		public bool AttackSpeedRestocks;

		public bool ManualRecharge;

		public float RestockMultiplier = 1f;

		public float Cooldown;

		public int Stock;
	}
	public sealed class ItemAdvice
	{
		public string Id;

		public string Reason;

		public int Count;

		public int Priority;

		public ItemAdvice(string id, int count, int priority, string reason)
		{
			Id = id;
			Count = count;
			Priority = priority;
			Reason = reason;
		}
	}
	public sealed class BuildPlan
	{
		public string Name;

		public string Evidence;

		public string Play;

		public string Confidence;

		public string EquipmentId;

		public string EquipmentReason;

		public readonly List<ItemAdvice> Items = new List<ItemAdvice>();

		public readonly List<string> Warnings = new List<string>();

		public void Add(string id, int count, int priority, string reason)
		{
			ItemAdvice itemAdvice = Items.Find((ItemAdvice i) => i.Id == id);
			if (itemAdvice == null)
			{
				Items.Add(new ItemAdvice(id, count, priority, reason));
				return;
			}
			itemAdvice.Count = Math.Max(itemAdvice.Count, count);
			itemAdvice.Priority = Math.Max(itemAdvice.Priority, priority);
			itemAdvice.Reason = itemAdvice.Reason + ";" + reason;
		}
	}
	public static class BuildLogic
	{
		public static readonly Dictionary<string, string> VoidPairs = new Dictionary<string, string>
		{
			{ "Bear", "BearVoid" },
			{ "CritGlasses", "CritGlassesVoid" },
			{ "ChainLightning", "ChainLightningVoid" },
			{ "Missile", "MissileVoid" },
			{ "Mushroom", "MushroomVoid" },
			{ "EquipmentMagazine", "EquipmentMagazineVoid" },
			{ "ExplodeOnDeath", "ExplodeOnDeathVoid" },
			{ "BleedOnHit", "BleedOnHitVoid" },
			{ "TreasureCache", "TreasureCacheVoid" },
			{ "ExtraLife", "ExtraLifeVoid" },
			{ "FireRing", "ElementalRingVoid" },
			{ "IceRing", "ElementalRingVoid" }
		};

		public static int Missing(int target, int have)
		{
			return Math.Max(0, Math.Min(100, target) - Math.Max(0, have));
		}

		private static bool Has(string text, params string[] words)
		{
			return words.Any((string w) => text.IndexOf(w, StringComparison.OrdinalIgnoreCase) >= 0);
		}

		private static int Count(IDictionary<string, int> inventory, string id)
		{
			if (!inventory.TryGetValue(id, out var value))
			{
				return 0;
			}
			return value;
		}

		public static BuildPlan Recommend(string bodyName, SkillEvidence[] skills, IDictionary<string, int> inventory, int style, int scale)
		{
			scale = Math.Max(1, Math.Min(3, scale));
			BuildPlan buildPlan = new BuildPlan();
			string text = string.Join(" ", skills.Select((SkillEvidence s) => s.Name + " " + s.Description + " " + s.InternalName));
			string text2 = string.Join(" ", from s in skills
				where s.Slot == "主要技能"
				select s.Name + " " + s.Description);
			bool flag = bodyName == "EngiBody";
			bool flag2 = flag && skills.Any((SkillEvidence s) => s.Slot == "特殊技能" && Has(s.InternalName, "EngiBodyPlaceTurret", "EngiBodyFireTurret", "ENGI_SPECIAL_NAME"));
			bool flag3 = flag && Has(text, "ENGI_SPECIAL_ALT1", "WalkerTurret", "移动炮塔", "移动</style>炮塔");
			flag2 = flag2 && !flag3;
			bool flag4 = new string[3] { "CommandoBody", "HuntressBody", "CaptainBody" }.Contains(bodyName);
			bool flag5 = new string[4] { "LoaderBody", "MageBody", "RailgunnerBody", "Bandit2Body" }.Contains(bodyName);
			bool flag6 = new string[5] { "MercBody", "LoaderBody", "CrocoBody", "FalseSonBody", "ChefBody" }.Contains(bodyName);
			bool flag7 = Has(text2, "连续", "连射", "机关枪", "rapid", "repeatedly", "automatic", "每秒", "per second", "nailgun", "钉枪");
			bool flag8 = Has(text, "蓄力", "charge up", "charged shot", "狙击", "sniper", "重拳");
			bool flag9 = Regex.Matches(text2, "(\\d+(?:\\.\\d+)?)\\s*%").Cast<Match>().Any((Match m) => double.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture) > 400.0);
			bool flag10 = flag6 || Has(text2, "近战", "melee", "斩击", "挥砍");
			bool flag11 = (flag4 || flag7) && !flag9;
			bool flag12 = flag5 || flag8 || flag9;
			bool flag13 = bodyName == "Bandit2Body";
			bool flag14 = bodyName == "RailgunnerBody";
			bool flag15 = Has(text, "必定暴击", "都会造成暴击", "always critically", "guaranteed critical");
			bool flag16 = Has(text, "炮塔", "turret");
			bool num = Has(text, "治疗", "恢复生命", "heal");
			List<string> list = new List<string>();
			if (flag7)
			{
				list.Add("主要技能说明包含连续/多次命中线索");
			}
			if (flag8 || flag9)
			{
				list.Add("技能说明包含蓄力或高倍率线索(不等同于已知触发系数)");
			}
			if (flag10)
			{
				list.Add("角色机制或主要技能提示近距离作战");
			}
			if (flag16)
			{
				list.Add("技能包含召唤炮塔;物品继承方式需看实际技能实现");
			}
			if (num)
			{
				list.Add("技能包含治疗线索,优先补机动和减伤");
			}
			if (flag15)
			{
				list.Add("技能说明包含必定暴击条件,不直接套用满暴击率目标");
			}
			if (skills.Any((SkillEvidence s) => s.Cooldown >= 8f && s.Slot != "被动技能"))
			{
				list.Add("存在较长冷却的技能,需管理爆发窗口");
			}
			bool flag17 = flag4 || flag5 || flag6 || flag || new string[3] { "TreebotBody", "VoidSurvivorBody", "SeekerBody" }.Contains(bodyName);
			buildPlan.Confidence = (flag17 ? "基础角色规则 + 当前技能文本;特殊技能变体仍需实测" : "文本推断;未读取到的触发系数、召唤物继承和隐藏机制均未知");
			if (list.Count == 0)
			{
				list.Add("技能信息不足,使用通用生存与机动作为起点");
			}
			buildPlan.Evidence = string.Join(";", list);
			int num2 = ((style != 0) ? style : (flag2 ? 4 : (flag11 ? 2 : (flag12 ? 3 : ((!flag10) ? 1 : 5)))));
			buildPlan.Name = (new string[6] { "自动分析", "稳健生存", "高频命中", "单次爆发", "固定炮台", "近战游走" })[num2];
			buildPlan.EquipmentId = num2 switch
			{
				5 => "GainArmor", 
				3 => "Blackhole", 
				2 => "CommandMissile", 
				_ => "Fruit", 
			};
			buildPlan.EquipmentReason = num2 switch
			{
				5 => "进入近战危险窗口前使用护甲装备;保护窗口结束后撤离,不把短时护甲当永久无敌。", 
				3 => "先聚拢小怪再使用范围技能,增加一次攻击覆盖的目标数;黑洞聚怪本身不等于触发手环。", 
				2 => "导弹装备补主动爆发;配合燃料电池可获得更多使用机会,战争号角可在使用后提供攻速窗口。", 
				_ => "保留一次主动治疗作为失误后的补救;固定炮台不会自动继承角色的主动装备使用。", 
			};
			buildPlan.Add("Hoof", scale + 1, (Count(inventory, "Hoof") == 0) ? 100 : 65, "持续移速帮助走位、跑图和躲避,不要求触发条件");
			buildPlan.Add("HealWhileSafe", 1, 85, "脱战后恢复;受伤时先拉开距离,不依赖站桩吸血");
			buildPlan.Add("Bear", scale, 78, "提供概率减伤;不能替代躲避,叠加收益不是简单线性相加");
			buildPlan.Add("Feather", 1, 82, "额外跳跃用于躲避和调整落点,不是直接增伤");
			buildPlan.Add("BarrierOnKill", scale, 76, "击杀杂兵获得临时屏障;对没有小怪的首领战收益有限");
			switch (num2)
			{
			case 1:
				buildPlan.Add("SprintBonus", scale, 72, "奔跑时加速,与常驻移速覆盖不同移动状态");
				buildPlan.Add("ArmorPlate", scale, 73, "削减小额多段伤害;大额攻击仍需躲避");
				buildPlan.Add("Crowbar", scale, 62, "提高满血敌人的起手伤害;持续作战中不能反复享受满血门槛");
				buildPlan.Play = "保持移动,先清小怪再打首领;受伤时脱战恢复。输出不足时再切换角色协同流派。";
				break;
			case 2:
				buildPlan.Add("Syringe", 2 * scale, 90, "若主要攻击受攻速影响,可增加命中机会;持续光束和固定射速技能需实测");
				buildPlan.Add("BleedOnHit", 2 * scale, 92, "更多有效命中可叠加流血,但实际触发几率还受技能触发系数影响");
				buildPlan.Add("Missile", scale, 84, "有效命中带来导弹机会;多段低触发系数技能不能仅按命中次数估算收益");
				buildPlan.Add("ChainLightning", 1, 87, "补范围清怪,配合击杀屏障形成清怪与生存联动");
				if (!flag13 && !flag14 && !flag15)
				{
					buildPlan.Add("CritGlasses", 2 * scale, 80, "为可暴击攻击补充暴击率;不要无限堆叠暴击率");
				}
				buildPlan.Play = "保持安全射程并持续命中。多段攻击不代表高触发效率;先观察流血、导弹和清怪效果再加量。";
				break;
			case 3:
				buildPlan.Add("Crowbar", 2 * scale, 95, "首发高伤害与敌人高生命门槛协同,优先处理未受伤的威胁目标");
				buildPlan.Add("FireRing", scale, 91, "需要单次命中达到手环门槛;多段伤害合计很高不保证触发");
				buildPlan.Add("IceRing", scale, 88, "补充爆发与减速,但与火环共享触发冷却,不能按两套独立冷却计算");
				buildPlan.Add("SecondarySkillMagazine", scale, 70, "增加次要技能充能,适合有价值的次要技能;不是所有角色都受益");
				buildPlan.Play = "先走位制造安全窗口,再用高伤害单次命中起手;手环冷却期间清杂兵、移动或等待下一轮。";
				if (flag14)
				{
					buildPlan.Warnings.Add("磁轨炮手:暴击率会转为暴击伤害,眼镜并非无效,但这里优先补起手爆发与机动。弱点命中与普通暴击不同。");
				}
				if (flag13)
				{
					buildPlan.Warnings.Add("盗贼:背后攻击已有必定暴击条件,优先改善绕后、起手伤害和生存,避免机械地堆满眼镜。");
				}
				break;
			case 4:
				buildPlan.Add("Mushroom", 2 * scale, 96, "仅在炮台静止且继承物品时,持续治疗区域才构成有效联动");
				buildPlan.Add("Syringe", 2 * scale, 88, "可受攻速影响的继承型炮台获得更高射击频率");
				buildPlan.Add("ChainLightning", 1, 85, "炮台命中触发范围输出,帮助清除围攻小怪");
				buildPlan.Add("Missile", scale, 82, "炮台高频命中提供额外触发机会;仍受炮台触发系数限制");
				buildPlan.Play = "把固定炮台放在能互相覆盖的位置,自己保持移动。移动炮台或不继承物品的召唤物应切换流派。";
				if (!flag2)
				{
					buildPlan.Warnings.Add("没有确认当前技能为原版固定炮台:真菌和物品继承联动仅是假设,请先实测。");
				}
				break;
			case 5:
				buildPlan.Add("NearbyDamageBonus", 2 * scale, 95, "近距离伤害增益与贴近目标的攻击方式协同;离开作用距离即无效");
				buildPlan.Add("ArmorPlate", scale, 80, "应对近战容易承受的小额连击,不用于硬扛首领大招");
				buildPlan.Add("SprintBonus", scale, 86, "帮助接近与撤离,降低为了输出而暴露的时间");
				buildPlan.Add("SecondarySkillMagazine", scale, 72, "有价值的次要技能增加使用次数;具体取决于当前技能变体");
				buildPlan.Add("Crowbar", scale, 78, "先手击杀脆弱目标,与击杀屏障构成接近、击杀、撤离循环");
				buildPlan.Play = "等敌人攻击结束后接近,优先击杀小怪取得屏障,再撤离危险范围。不要为了水晶加成一直站在首领脚下。";
				break;
			}
			if (flag3)
			{
				buildPlan.Warnings.Add("检测到移动炮台:不自动推荐爆裂真菌,移动会打断其静止条件。");
			}
			if (flag10 && num2 != 5 && num2 != 1)
			{
				buildPlan.Add("NearbyDamageBonus", scale, 89, "技能显示近距离作战需求,即使以高频或爆发为主,也可叠加近距离增伤条件");
			}
			if (flag15 && !flag13)
			{
				buildPlan.Warnings.Add("文本提示条件暴击:需要实际满足该条件,不能理解为全程必定暴击。");
			}
			if (Count(inventory, "CritGlasses") >= 10 && !flag14)
			{
				buildPlan.Items.RemoveAll((ItemAdvice i) => i.Id == "CritGlasses");
				buildPlan.Warnings.Add("已有至少10层眼镜,不再建议继续堆原版暴击率;特殊 Mod 改写上限时需自行调配。");
			}
			if (Count(inventory, "ChainLightning") > 0 && Count(inventory, "BarrierOnKill") == 0)
			{
				buildPlan.Add("BarrierOnKill", scale, 94, "你已有连锁清怪能力,补击杀屏障可把清怪速度转化为短时生存能力");
			}
			if (Count(inventory, "CritGlasses") >= 8 && !flag13 && !flag14)
			{
				buildPlan.Add("HealOnCrit", 1, 90, "已有较高暴击率时,暴击治疗可与攻击频率联动;仍不能保证扛住大额伤害");
			}
			if (Count(inventory, "BearVoid") > 0)
			{
				buildPlan.Warnings.Add("已持有更安全的空间:原版小熊会被虚空替代,自动补齐会跳过原版小熊。");
			}
			foreach (KeyValuePair<string, string> pair in VoidPairs)
			{
				if (Count(inventory, pair.Value) > 0)
				{
					buildPlan.Items.RemoveAll((ItemAdvice i) => i.Id == pair.Key);
				}
			}
			buildPlan.Warnings.Add("本推荐是机制分析与条件推断,不是伤害模拟器。隐藏触发系数、Mod 改写和技能实际命中表现可能改变收益。");
			return buildPlan;
		}
	}
	[HarmonyPatch(typeof(PickupPickerPanel), "SetPickupOptions")]
	internal static class PickerPatch
	{
		private static void Postfix(PickupPickerPanel __instance, Option[] __0)
		{
			if (Object.op_Implicit((Object)(object)Plugin.Instance) && Object.op_Implicit((Object)(object)__instance))
			{
				AdvisorPickerBridge advisorPickerBridge = ((Component)__instance).GetComponent<AdvisorPickerBridge>();
				if (!Object.op_Implicit((Object)(object)advisorPickerBridge))
				{
					advisorPickerBridge = ((Component)__instance).gameObject.AddComponent<AdvisorPickerBridge>();
				}
				advisorPickerBridge.Set(__instance, __0);
			}
		}
	}
	public sealed class AdvisorPickerBridge : MonoBehaviour
	{
		internal PickupPickerPanel Panel;

		internal Option[] Options;

		private readonly List<NativePickerMark> marks = new List<NativePickerMark>();

		private float next;

		private int version = -1;

		private int lastAvailability;

		private bool dirty = true;

		private bool failed;

		internal bool IsCommand
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Panel) && Object.op_Implicit((Object)(object)Panel.pickerController))
				{
					return ((Object)Panel.pickerController).name.IndexOf("CommandCube", StringComparison.OrdinalIgnoreCase) >= 0;
				}
				return false;
			}
		}

		internal void Set(PickupPickerPanel panel, Option[] options)
		{
			Restore();
			Panel = panel;
			Options = options;
			dirty = true;
			failed = false;
			if (Object.op_Implicit((Object)(object)Plugin.Instance))
			{
				Plugin.Instance.RegisterPicker(this);
			}
		}

		private void LateUpdate()
		{
			//IL_0260: 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)
			Plugin instance = Plugin.Instance;
			if (!Object.op_Implicit((Object)(object)instance) || !IsCommand)
			{
				Restore();
				return;
			}
			instance.RegisterPicker(this);
			if (!instance.ShouldEnhance(this))
			{
				Restore();
			}
			else
			{
				if (failed || Time.unscaledTime < next)
				{
					return;
				}
				next = Time.unscaledTime + 0.2f;
				try
				{
					UIElementAllocator<MPButton> value = Traverse.Create((object)Panel).Field("buttonAllocator").GetValue<UIElementAllocator<MPButton>>();
					if (value == null || Options == null)
					{
						return;
					}
					int num = Math.Min(Options.Length, value.elements.Count);
					bool flag = marks.Count != num;
					int num2 = 0;
					while (!flag && num2 < num)
					{
						flag = !Object.op_Implicit((Object)(object)marks[num2]) || (Object)(object)marks[num2].Button != (Object)(object)value.elements[num2];
						num2++;
					}
					if (flag)
					{
						Restore();
						for (int i = 0; i < num; i++)
						{
							MPButton val = value.elements[i];
							if (!Object.op_Implicit((Object)(object)val))
							{
								Restore();
								return;
							}
							NativePickerMark nativePickerMark = ((Component)val).gameObject.AddComponent<NativePickerMark>();
							marks.Add(nativePickerMark);
							nativePickerMark.Initialize(val);
						}
						dirty = true;
					}
					int num3 = 17;
					for (int j = 0; j < num; j++)
					{
						num3 = num3 * 31 + (Options[j].available ? 1 : 0) + (((Selectable)value.elements[j]).interactable ? 2 : 0);
						if (marks[j].NeedsRefresh)
						{
							dirty = true;
						}
					}
					if (num3 != lastAvailability)
					{
						lastAvailability = num3;
						dirty = true;
					}
					if (!dirty && version == instance.RecommendationVersion)
					{
						return;
					}
					dirty = false;
					version = instance.RecommendationVersion;
					double num4 = 0.0;
					for (int k = 0; k < num; k++)
					{
						if (Options[k].available && ((Selectable)value.elements[k]).interactable)
						{
							num4 = Math.Max(num4, instance.PickerScore(PickupCatalog.GetPickupDef(Options[k].pickup.pickupIndex)));
						}
					}
					for (int l = 0; l < num; l++)
					{
						PickupDef pickupDef = PickupCatalog.GetPickupDef(Options[l].pickup.pickupIndex);
						int level = PriorityLogic.Classify(instance.PickerScore(pickupDef), num4, Options[l].available && ((Selectable)value.elements[l]).interactable);
						marks[l].Paint(level, pickupDef, instance.PickerReason(pickupDef, level, num4));
					}
				}
				catch (Exception ex)
				{
					Restore();
					failed = true;
					instance.PickerFailure(ex);
				}
			}
		}

		internal void Retry()
		{
			failed = false;
			dirty = true;
			next = 0f;
		}

		internal void Restore()
		{
			foreach (NativePickerMark mark in marks)
			{
				if (Object.op_Implicit((Object)(object)mark))
				{
					mark.Restore();
					((Behaviour)mark).enabled = false;
					Object.Destroy((Object)(object)mark);
				}
			}
			marks.Clear();
			dirty = true;
			version = -1;
		}

		private void OnDisable()
		{
			Restore();
		}

		private void OnDestroy()
		{
			Restore();
		}
	}
	public sealed class NativePickerMark : MonoBehaviour
	{
		internal MPButton Button;

		private GameObject root;

		private readonly List<Image> borders = new List<Image>();

		private TextMeshProUGUI badge;

		private TooltipProvider tooltip;

		private bool createdTooltip;

		private bool originalEnabled;

		private string originalBody;

		private string lastBody;

		private string lastAddition;

		private string createdTitle;

		private string createdToken;

		private static readonly Color[] Colors = (Color[])(object)new Color[5]
		{
			Color.clear,
			new Color(0.56f, 0.63f, 0.72f),
			new Color(0.43f, 0.8f, 0.53f),
			new Color(0.36f, 0.82f, 0.95f),
			new Color(1f, 0.79f, 0.3f)
		};

		internal bool NeedsRefresh
		{
			get
			{
				if (Object.op_Implicit((Object)(object)root) && root.activeSelf)
				{
					if (Object.op_Implicit((Object)(object)tooltip) && ((Behaviour)tooltip).enabled)
					{
						return tooltip.overrideBodyText != lastBody;
					}
					return true;
				}
				return false;
			}
		}

		internal void Initialize(MPButton button)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_006e: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: 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_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			Button = button;
			TextMeshProUGUI componentInChildren = ((Component)button).GetComponentInChildren<TextMeshProUGUI>();
			if (!Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren = ((Component)((Component)this).GetComponentInParent<PickupPickerPanel>()).GetComponentInChildren<TextMeshProUGUI>();
			}
			root = new GameObject("BeginnerBuilds_Priority", new Type[1] { typeof(RectTransform) });
			root.transform.SetParent(((Component)button).transform, false);
			RectTransform val = (RectTransform)root.transform;
			val.anchorMin = Vector2.zero;
			val.anchorMax = Vector2.one;
			Vector2 val2 = (val.offsetMin = (val.offsetMax = Vector2.zero));
			root.AddComponent<LayoutElement>().ignoreLayout = true;
			CanvasGroup obj = root.AddComponent<CanvasGroup>();
			obj.interactable = false;
			obj.blocksRaycasts = false;
			for (int i = 0; i < 4; i++)
			{
				GameObject val4 = new GameObject("PriorityBorder", new Type[1] { typeof(RectTransform) });
				val4.transform.SetParent((Transform)(object)val, false);
				RectTransform val5 = (RectTransform)val4.transform;
				if (i < 2)
				{
					val5.anchorMin = new Vector2(0f, (float)i);
					val5.anchorMax = new Vector2(1f, (float)i);
					val5.pivot = new Vector2(0.5f, (float)i);
					val5.sizeDelta = new Vector2(-4f, 2f);
					val5.anchoredPosition = new Vector2(0f, (float)((i == 0) ? 2 : (-2)));
				}
				else
				{
					val5.anchorMin = new Vector2((float)(i - 2), 0f);
					val5.anchorMax = new Vector2((float)(i - 2), 1f);
					val5.pivot = new Vector2((float)(i - 2), 0.5f);
					val5.sizeDelta = new Vector2(2f, -4f);
					val5.anchoredPosition = new Vector2((float)((i == 2) ? 2 : (-2)), 0f);
				}
				Image val6 = val4.AddComponent<Image>();
				((Graphic)val6).raycastTarget = false;
				borders.Add(val6);
			}
			GameObject val7 = new GameObject("PriorityBadge", new Type[1] { typeof(RectTransform) });
			val7.transform.SetParent((Transform)(object)val, false);
			RectTransform val8 = (RectTransform)val7.transform;
			((Vector2)(ref val2))..ctor(0f, 1f);
			val8.anchorMax = val2;
			val8.anchorMin = val2;
			val8.pivot = new Vector2(0f, 1f);
			val8.anchoredPosition = new Vector2(3f, -3f);
			val8.sizeDelta = new Vector2(19f, 17f);
			Image obj2 = val7.AddComponent<Image>();
			((Graphic)obj2).color = new Color(0.025f, 0.03f, 0.035f, 0.88f);
			((Graphic)obj2).raycastTarget = false;
			GameObject val9 = new GameObject("Level", new Type[1] { typeof(RectTransform) });
			val9.transform.SetParent((Transform)(object)val8, false);
			RectTransform val10 = (RectTransform)val9.transform;
			val10.anchorMin = Vector2.zero;
			val10.anchorMax = Vector2.one;
			val2 = (val10.offsetMin = (val10.offsetMax = Vector2.zero));
			badge = (TextMeshProUGUI)(object)val9.AddComponent<HGTextMeshProUGUI>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				((TMP_Text)badge).font = ((TMP_Text)componentInChildren).font;
				((TMP_Text)badge).fontSharedMaterial = ((TMP_Text)componentInChildren).fontSharedMaterial;
			}
			if (!Object.op_Implicit((Object)(object)((TMP_Text)badge).font))
			{
				((TMP_Text)badge).font = TMP_Settings.defaultFontAsset;
			}
			((TMP_Text)badge).fontSize = 13f;
			((TMP_Text)badge).fontStyle = (FontStyles)1;
			((TMP_Text)badge).alignment = (TextAlignmentOptions)514;
			((Graphic)badge).raycastTarget = false;
			((TMP_Text)badge).enableWordWrapping = false;
			root.SetActive(false);
		}

		internal void Paint(int level, PickupDef pickup, string reason)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			root.SetActive(level > 0);
			if (level > 0)
			{
				foreach (Image border in borders)
				{
					((Graphic)border).color = Colors[level];
				}
				((TMP_Text)badge).text = (new string[5] { "", "C", "B", "A", "S" })[level];
				((Graphic)badge).color = Colors[level];
			}
			if (level <= 0)
			{
				RestoreTooltip();
				return;
			}
			if (!Object.op_Implicit((Object)(object)tooltip))
			{
				tooltip = ((Component)Button).GetComponent<TooltipProvider>();
				if (!Object.op_Implicit((Object)(object)tooltip))
				{
					tooltip = ((Component)Button).gameObject.AddComponent<TooltipProvider>();
					createdTooltip = true;
					ItemDef val = ((pickup == null) ? null : ItemCatalog.GetItemDef(pickup.itemIndex));
					EquipmentDef val2 = ((pickup == null) ? null : EquipmentCatalog.GetEquipmentDef(pickup.equipmentIndex));
					tooltip.titleToken = pickup?.nameToken;
					tooltip.bodyToken = (Object.op_Implicit((Object)(object)val) ? val.descriptionToken : (Object.op_Implicit((Object)(object)val2) ? val2.descriptionToken : pickup?.pickupToken));
					createdTitle = tooltip.titleToken;
					createdToken = tooltip.bodyToken;
				}
				originalBody = tooltip.overrideBodyText;
				originalEnabled = ((Behaviour)tooltip).enabled;
			}
			else if (lastBody != null && tooltip.overrideBodyText != lastBody)
			{
				originalBody = TooltipText.RemoveOwned(tooltip.overrideBodyText, lastAddition);
				originalEnabled = ((Behaviour)tooltip).enabled;
			}
			string text = (string.IsNullOrEmpty(originalBody) ? Language.GetString(tooltip.bodyToken ?? "") : originalBody);
			lastAddition = "\n\n" + reason;
			lastBody = text + lastAddition;
			tooltip.overrideBodyText = lastBody;
			((Behaviour)tooltip).enabled = true;
		}

		private void RestoreTooltip()
		{
			if (Object.op_Implicit((Object)(object)tooltip))
			{
				bool flag = tooltip.overrideBodyText == lastBody;
				if (createdTooltip && flag && tooltip.titleToken == createdTitle && tooltip.bodyToken == createdToken)
				{
					((Behaviour)tooltip).enabled = false;
					Object.Destroy((Object)(object)tooltip);
				}
				else if (flag)
				{
					tooltip.overrideBodyText = originalBody;
					((Behaviour)tooltip).enabled = originalEnabled;
				}
				else
				{
					tooltip.overrideBodyText = TooltipText.RemoveOwned(tooltip.overrideBodyText, lastAddition);
				}
			}
			tooltip = null;
			createdTooltip = false;
			originalBody = (lastBody = (lastAddition = null));
			createdTitle = (createdToken = null);
		}

		internal void Restore()
		{
			if (Object.op_Implicit((Object)(object)root))
			{
				root.SetActive(false);
				Object.Destroy((Object)(object)root);
				root = null;
			}
			RestoreTooltip();
		}

		private void OnDestroy()
		{
			Restore();
		}
	}
	[DefaultExecutionOrder(-20000)]
	[BepInPlugin("local.beginnerbuilds.assistant", "新手流派助手", "0.6.3")]
	public class Plugin : BaseUnityPlugin
	{
		private sealed class NativeMenu : IDisposable
		{
			private readonly Plugin p;

			private readonly GameObject root;

			private readonly RectTransform canvasRect;

			private readonly RectTransform shell;

			private readonly RectTransform body;

			private readonly RectTransform sidebar;

			private readonly Image shade;

			private readonly AdvicePointer pointer;

			private readonly TextMeshProUGUI role;

			private readonly TextMeshProUGUI summary;

			private readonly TextMeshProUGUI statusText;

			private TMP_FontAsset nativeFont;

			private Material nativeMaterial;

			private ScrollRect scroll;

			private RectTransform content;

			private GameObject confirmation;

			private bool dirty = true;

			private bool shown;

			private string stamp = "";

			private int builtWorkspace = -1;

			private float y;

			private float width = 1010f;

			internal readonly EventSystem EventSystem;

			private static readonly Color Paper = new Color(0.94f, 0.94f, 0.9f);

			private static readonly Color Muted = new Color(0.62f, 0.65f, 0.65f);

			private static readonly Color Gold = new Color(0.95f, 0.76f, 0.36f);

			internal NativeMenu(Plugin plugin)
			{
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Expected O, but got Unknown
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_0092: Expected O, but got Unknown
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01df: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fd: 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_0270: 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_02dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0426: Unknown result type (might be due to invalid IL or missing references)
				//IL_042c: Unknown result type (might be due to invalid IL or missing references)
				//IL_042d: Unknown result type (might be due to invalid IL or missing references)
				//IL_042e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0434: Unknown result type (might be due to invalid IL or missing references)
				//IL_0445: Unknown result type (might be due to invalid IL or missing references)
				p = plugin;
				root = new GameObject("BeginnerBuilds_NativeModal", new Type[1] { typeof(RectTransform) });
				root.SetActive(false);
				root.transform.SetParent(((Component)p).transform, false);
				canvasRect = (RectTransform)root.transform;
				Canvas obj = root.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 32750;
				CanvasScaler obj2 = root.AddComponent<CanvasScaler>();
				obj2.uiScaleMode = (ScaleMode)1;
				obj2.referenceResolution = new Vector2(1600f, 900f);
				obj2.matchWidthOrHeight = 0.5f;
				root.AddComponent<GraphicRaycaster>();
				EventSystem = root.AddComponent<EventSystem>();
				((Behaviour)EventSystem).enabled = false;
				EventSystem.sendNavigationEvents = false;
				root.AddComponent<ModalMouseInput>();
				FindFont();
				if (!Object.op_Implicit((Object)(object)nativeFont))
				{
					throw new InvalidOperationException("游戏字体尚未就绪;已取消界面接管,请稍后再按F2。");
				}
				shade = Panel("ModalBlocker", (Transform)(object)canvasRect, 0f, 0f, 1600f, 900f, new Color(0f, 0f, 0f, 0.68f));
				Stretch(((Graphic)shade).rectTransform);
				((Graphic)shade).raycastTarget = true;
				shell = Box("Menu", (Transform)(object)canvasRect);
				RectTransform obj3 = shell;
				RectTransform obj4 = shell;
				RectTransform obj5 = shell;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				obj5.pivot = val;
				obj3.anchorMin = (obj4.anchorMax = val);
				shell.sizeDelta = new Vector2(1280f, 760f);
				Image obj6 = ((Component)shell).gameObject.AddComponent<Image>();
				((Graphic)obj6).color = new Color(0.055f, 0.065f, 0.07f, 0.985f);
				((Graphic)obj6).raycastTarget = true;
				Panel("HeaderRule", (Transform)(object)shell, 24f, 74f, 1232f, 1f, new Color(1f, 1f, 1f, 0.09f));
				role = Text("Role", (Transform)(object)shell, 26f, 17f, 800f, 30f, 24f, Paper);
				summary = Text("Context", (Transform)(object)shell, 27f, 49f, 970f, 20f, 13f, Muted);
				Button("重新检测", (Transform)(object)shell, 1058f, 24f, 100f, 34f, delegate
				{
					p.Refresh();
					dirty = true;
				});
				Button("关闭 ×", (Transform)(object)shell, 1168f, 24f, 86f, 34f, delegate
				{
					p.SetOpen(value: false);
				});
				sidebar = Box("Navigation", (Transform)(object)shell);
				Place(sidebar, 24f, 94f, 174f, 590f);
				body = Box("Page", (Transform)(object)shell);
				Place(body, 222f, 94f, 1034f, 606f);
				statusText = Text("Status", (Transform)(object)shell, 24f, 718f, 1228f, 24f, 13f, Muted);
				RectTransform val3 = Box("VisiblePointer", (Transform)(object)canvasRect);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				val3.pivot = val;
				val3.anchorMin = (val3.anchorMax = val);
				val3.sizeDelta = new Vector2(24f, 28f);
				pointer = ((Component)val3).gameObject.AddComponent<AdvicePointer>();
				((Graphic)pointer).raycastTarget = false;
			}

			private void FindFont()
			{
				TextMeshProUGUI val = null;
				foreach (HUD readOnlyInstance in HUD.readOnlyInstanceList)
				{
					if (Object.op_Implicit((Object)(object)readOnlyInstance))
					{
						val = (TextMeshProUGUI)(object)((Component)readOnlyInstance).GetComponentInChildren<HGTextMeshProUGUI>(true);
						if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((TMP_Text)val).font))
						{
							break;
						}
					}
				}
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = ((IEnumerable<TextMeshProUGUI>)Object.FindObjectsOfType<TextMeshProUGUI>()).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => Object.op_Implicit((Object)(object)((TMP_Text)t).font)));
				}
				nativeFont = (Object.op_Implicit((Object)(object)val) ? ((TMP_Text)val).font : TMP_Settings.defaultFontAsset);
				nativeMaterial = (Object.op_Implicit((Object)(object)val) ? ((TMP_Text)val).fontSharedMaterial : null);
			}

			private RectTransform Box(string name, Transform parent)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Expected O, but got Unknown
				GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(parent, false);
				RectTransform val2 = (RectTransform)val.transform;
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(0f, 1f);
				val2.pivot = val3;
				Vector2 anchorMin = (val2.anchorMax = val3);
				val2.anchorMin = anchorMin;
				return val2;
			}

			private void Place(RectTransform r, float x, float top, float w, float h)
			{
				//IL_0004: 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)
				r.anchoredPosition = new Vector2(x, 0f - top);
				r.sizeDelta = new Vector2(w, h);
			}

			private void Stretch(RectTransform r)
			{
				//IL_0001: 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_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_0024: Unknown result type (might be due to invalid IL or missing references)
				r.anchorMin = Vector2.zero;
				r.anchorMax = Vector2.one;
				Vector2 offsetMin = (r.offsetMax = Vector2.zero);
				r.offsetMin = offsetMin;
			}

			private Image Panel(string name, Transform parent, float x, float top, float w, float h, Color color)
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				RectTransform val = Box(name, parent);
				Place(val, x, top, w, h);
				Image obj = ((Component)val).gameObject.AddComponent<Image>();
				((Graphic)obj).color = color;
				((Graphic)obj).raycastTarget = false;
				return obj;
			}

			private TextMeshProUGUI Text(string name, Transform parent, float x, float top, float w, float h, float size, Color color, string value = "", bool wrap = false)
			{
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				RectTransform val = Box(name, parent);
				Place(val, x, top, w, h);
				HGTextMeshProUGUI val2 = ((Component)val).gameObject.AddComponent<HGTextMeshProUGUI>();
				if (Object.op_Implicit((Object)(object)nativeFont))
				{
					((TMP_Text)val2).font = nativeFont;
				}
				if (Object.op_Implicit((Object)(object)nativeMaterial))
				{
					((TMP_Text)val2).fontSharedMaterial = nativeMaterial;
				}
				((TMP_Text)val2).fontSize = size;
				((TMP_Text)val2).fontSizeMin = size;
				((TMP_Text)val2).fontSizeMax = size;
				((TMP_Text)val2).enableAutoSizing = false;
				((TMP_Text)val2).enableWordWrapping = wrap;
				((TMP_Text)val2).richText = false;
				((TMP_Text)val2).overflowMode = (TextOverflowModes)1;
				((TMP_Text)val2).alignment = (TextAlignmentOptions)4097;
				((Graphic)val2).color = color;
				((Graphic)val2).raycastTarget = false;
				((TMP_Text)val2).text = value;
				return (TextMeshProUGUI)(object)val2;
			}

			private Button Button(string label, Transform parent, float x, float top, float w, float h, Action action, bool selected = false)
			{
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Expected O, but got Unknown
				Image val = Panel(label, parent, x, top, w, h, selected ? new Color(0.25f, 0.23f, 0.16f) : new Color(0.13f, 0.15f, 0.16f));
				((Graphic)val).raycastTarget = true;
				Button obj = ((Component)val).gameObject.AddComponent<Button>();
				((Selectable)obj).targetGraphic = (Graphic)(object)val;
				ColorBlock colors = ((Selectable)obj).colors;
				((ColorBlock)(ref colors)).normalColor = Color.white;
				((ColorBlock)(ref colors)).highlightedColor = new Color(1.3f, 1.3f, 1.2f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.85f, 0.85f, 0.8f);
				((ColorBlock)(ref colors)).selectedColor = ((ColorBlock)(ref colors)).highlightedColor;
				((Selectable)obj).colors = colors;
				Navigation navigation = default(Navigation);
				((Navigation)(ref navigation)).mode = (Mode)0;
				((Selectable)obj).navigation = navigation;
				((TMP_Text)Text("Label", ((Component)val).transform, 8f, 0f, w - 16f, h, 15f, selected ? Gold : Paper, label)).alignment = (TextAlignmentOptions)514;
				((UnityEvent)obj.onClick).AddListener((UnityAction)delegate
				{
					p.Defer(delegate
					{
						action();
						dirty = true;
					});
				});
				return obj;
			}

			private void Icon(Transform parent, float x, float top, float size, Func<Sprite> resolve)
			{
				//IL_0021: 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_0083: Unknown result type (might be due to invalid IL or missing references)
				Image val = Panel("IconFrame", parent, x, top, size, size, new Color(1f, 1f, 1f, 0.035f));
				Image val2 = Panel("Icon", ((Component)val).transform, 3f, 3f, size - 6f, size - 6f, Color.white);
				val2.preserveAspect = true;
				TextMeshProUGUI val3 = Text("Loading", ((Component)val).transform, 0f, 0f, size, size, 13f, Muted, "…");
				((TMP_Text)val3).alignment = (TextAlignmentOptions)514;
				AsyncAdviceIcon asyncAdviceIcon = ((Component)val).gameObject.AddComponent<AsyncAdviceIcon>();
				asyncAdviceIcon.Resolve = resolve;
				asyncAdviceIcon.Image = val2;
				asyncAdviceIcon.Loading = val3;
			}

			internal void Activate(bool showMenu)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				root.SetActive(true);
				if (!showMenu)
				{
					CancelConfirmation();
				}
				shown = showMenu;
				((Component)shell).gameObject.SetActive(showMenu);
				((Graphic)shade).color = new Color(0f, 0f, 0f, showMenu ? 0.68f : 0f);
				((Component)pointer).gameObject.SetActive(showMenu);
			}

			internal bool CancelConfirmation()
			{
				if (!Object.op_Implicit((Object)(object)confirmation))
				{
					return false;
				}
				Object.Destroy((Object)(object)confirmation);
				confirmation = null;
				p.confirm = false;
				return true;
			}

			internal void Hide()
			{
				CancelConfirmation();
				root.SetActive(false);
			}

			internal void Invalidate()
			{
				dirty = true;
			}

			internal void Tick()
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: 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_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				Vector2 anchoredPosition = default(Vector2);
				RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, Vector2.op_Implicit(Input.mousePosition), (Camera)null, ref anchoredPosition);
				((Graphic)pointer).rectTransform.anchoredPosition = anchoredPosition;
				((Component)pointer).transform.SetAsLastSibling();
				Rect rect = canvasRect.rect;
				float num = ((Rect)(ref rect)).width;
				rect = canvasRect.rect;
				float num2 = LayoutRules.FitMenu(num, ((Rect)(ref rect)).height, p.interfaceScale.Value);
				((Transform)shell).localScale = Vector3.one * num2;
				if (!shown)
				{
					return;
				}
				if (Object.op_Implicit((Object)(object)confirmation) && (!p.confirm || p.Signature != p.confirmSignature))
				{
					p.status = "配装预览已过期,请重新预览确认。";
					CancelConfirmation();
				}
				((TMP_Text)role).text = p.bodyLabel;
				((TMP_Text)summary).text = p.detection + "  ·  " + ((p.plan == null) ? "等待分析" : p.plan.Name);
				((TMP_Text)statusText).text = p.status;
				string text = p.workspace + "/" + p.bodyId + "/" + p.lastDetectedSkills;
				if (p.workspace == 1)
				{
					text = text + "/" + p.style.Value + "/" + string.Join(";", p.routeOptions.Select((RouteOption r) => r.Style + ":" + r.Support));
				}
				if (p.workspace == 0)
				{
					text = text + "/" + string.Join(";", p.growthPicks.Select((GrowthPick g) => g.Id + ":" + g.Have + ":" + Math.Round(g.Score, 1)));
				}
				if (text != stamp)
				{
					stamp = text;
					dirty = true;
				}
				GameObject currentSelectedGameObject = EventSystem.currentSelectedGameObject;
				TMP_InputField val = (Object.op_Implicit((Object)(object)currentSelectedGameObject) ? currentSelectedGameObject.GetComponent<TMP_InputField>() : null);
				if (dirty && !Input.GetMouseButton(0) && (!Object.op_Implicit((Object)(object)val) || !val.isFocused))
				{
					dirty = false;
					Rebuild();
				}
			}

			private void Clear(Transform parent)
			{
				for (int num = parent.childCount - 1; num >= 0; num--)
				{
					GameObject gameObject = ((Component)parent.GetChild(num)).gameObject;
					gameObject.SetActive(false);
					Object.Destroy((Object)(object)gameObject);
				}
			}

			private void Rebuild()
			{
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0145: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_023a: Unknown result type (might be due to invalid IL or missing references)
				//IL_027b: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_034a: Unknown result type (might be due to invalid IL or missing references)
				float verticalNormalizedPosition = ((Object.op_Implicit((Object)(object)scroll) && builtWorkspace == p.workspace) ? scroll.verticalNormalizedPosition : 1f);
				builtWorkspace = p.workspace;
				Clear((Transform)(object)sidebar);
				Clear((Transform)(object)body);
				string[] array = new string[4] { "下一件推荐", "配装与体验", "角色与技能", "显示与操作" };
				for (int i = 0; i < array.Length; i++)
				{
					int index = i;
					Button(array[i], (Transform)(object)sidebar, 0f, i * 54, 174f, 44f, delegate
					{
						p.workspace = index;
					}, i == p.workspace);
				}
				Text("Help", (Transform)(object)sidebar, 8f, 470f, 160f, 98f, 13f, Muted, "F2 / Esc 关闭\nF3 推荐HUD\n更改后自动保留\n关闭菜单时保存", wrap: true);
				Image val = Panel("Scroll", (Transform)(object)body, 0f, 0f, 1034f, 606f, Color.clear);
				((Graphic)val).raycastTarget = true;
				((Component)val).gameObject.AddComponent<RectMask2D>();
				scroll = ((Component)val).gameObject.AddComponent<ScrollRect>();
				scroll.horizontal = false;
				scroll.vertical = true;
				scroll.movementType = (MovementType)2;
				scroll.scrollSensitivity = 28f;
				content = Box("Content", ((Component)val).transform);
				content.sizeDelta = new Vector2(1010f, 606f);
				scroll.viewport = ((Graphic)val).rectTransform;
				scroll.content = content;
				y = 0f;
				Image val2 = Panel("ScrollRail", (Transform)(object)body, 1022f, 0f, 8f, 606f, new Color(1f, 1f, 1f, 0.035f));
				((Graphic)val2).raycastTarget = true;
				Image val3 = Panel("ScrollThumb", ((Component)val2).transform, 0f, 0f, 8f, 80f, new Color(0.42f, 0.45f, 0.44f));
				((Graphic)val3).raycastTarget = true;
				Scrollbar val4 = ((Component)val2).gameObject.AddComponent<Scrollbar>();
				val4.direction = (Direction)2;
				val4.handleRect = ((Graphic)val3).rectTransform;
				((Selectable)val4).targetGraphic = (Graphic)(object)val3;
				Navigation navigation = default(Navigation);
				((Navigation)(ref navigation)).mode = (Mode)0;
				((Selectable)val4).navigation = navigation;
				scroll.verticalScrollbar = val4;
				if (p.workspace == 0)
				{
					Home();
				}
				else if (p.workspace == 1)
				{
					Loadout();
				}
				else if (p.workspace == 2)
				{
					Skills();
				}
				else
				{
					Settings();
				}
				content.sizeDelta = new Vector2(width, Mathf.Max(606f, y + 20f));
				scroll.verticalNormalizedPosition = verticalNormalizedPosition;
			}

			private void Heading(string text, string sub = "")
			{
				//IL_0027: 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)
				Text("Heading", (Transform)(object)content, 0f, y, width, 32f, 23f, Paper, text);
				y += 38f;
				if (sub != "")
				{
					Text("Subheading", (Transform)(object)content, 0f, y, width, 42f, 14f, Muted, sub, wrap: true);
					y += 48f;
				}
			}

			private void Home()
			{
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_037a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0247: 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_0470: Unknown result type (might be due to invalid IL or missing references)
				//IL_058d: Unknown result type (might be due to invalid IL or missing references)
				//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_0668: Unknown result type (might be due to invalid IL or missing references)
				//IL_0765: Unknown result type (might be due to invalid IL or missing references)
				//IL_086c: Unknown result type (might be due to invalid IL or missing references)
				//IL_08ce: Unknown result type (might be due to invalid IL or missing references)
				Heading("下一件怎么选", "按当前技能、背包和物品品质分别推荐;软参考量不是硬上限。");
				if (p.beginnerHelp.Value)
				{
					Text("Beginner", (Transform)(object)content, 0f, y, width, 58f, 16f, Paper, p.BeginnerSummary(), wrap: true);
					y += 70f;
				}
				GrowthPick[] array = new GrowthPick[3]
				{
					p.BestForTier(1),
					p.BestForTier(2),
					p.BestForTier(3)
				};
				for (int i = 0; i < 3; i++)
				{
					GrowthPick growthPick = array[i];
					float num = i * 338;
					Panel("Card", (Transform)(object)content, num, y, 326f, 146f, new Color(0.1f, 0.12f, 0.13f));
					if (growthPick == null)
					{
						Text("Empty", (Transform)(object)content, num + 14f, y + 25f, 298f, 60f, 15f, Muted, "本品质暂无有依据的建议", wrap: true);
						continue;
					}
					ItemDef def = p.Def(growthPick.Id);
					Color color = (Object.op_Implicit((Object)(object)def) ? Color32.op_Implicit(ColorCatalog.GetColor(def.colorIndex)) : Paper);
					Text("Tier", (Transform)(object)content, num + 14f, y + 10f, 290f, 22f, 13f, color, p.TierLabel(growthPick.Id) + "优先");
					Icon((Transform)(object)content, num + 14f, y + 42f, 58f, () => p.ItemIcon(def));
					Text("Name", (Transform)(object)content, num + 84f, y + 41f, 228f, 30f, 18f, Paper, p.PickName(growthPick.Id));
					Text("Count", (Transform)(object)content, num + 84f, y + 74f, 224f, 24f, 13f, Muted, "已有 " + growthPick.Have + " / 参考 " + growthPick.SoftGoal + " · " + growthPick.Category);
					string id = growthPick.Id;
					Button("查看联动与下一层收益", (Transform)(object)content, num + 14f, y + 108f, 298f, 28f, delegate
					{
						p.selectedGrowth = id;
					});
				}
				y += 162f;
				Text("Focus", (Transform)(object)content, 0f, y, 90f, 34f, 14f, Muted, "当前优先");
				string[] array2 = new string[4] { "均衡成长", "补生存", "补输出", "补机动" };
				for (int num2 = 0; num2 < 4; num2++)
				{
					int n = num2;
					Button(array2[num2], (Transform)(object)content, 100 + num2 * 132, y, 122f, 34f, delegate
					{
						p.growthFocus.Value = n;
						p.Refresh();
					}, p.growthFocus.Value == num2);
				}
				y += 50f;
				if (p.transition != null)
				{
					Text("Transition", (Transform)(object)content, 0f, y, 770f, 48f, 15f, Gold, "可考虑转向「" + p.transition.Name + "」:" + p.transition.Reason + "。不会自动切换。", wrap: true);
					Button("查看流派路线", (Transform)(object)content, 810f, y + 5f, 190f, 34f, delegate
					{
						p.workspace = 1;
					});
					y += 60f;
				}
				GrowthPick growthPick2 = p.Growth(p.selectedGrowth) ?? array.FirstOrDefault((GrowthPick g) => g != null);
				if (growthPick2 != null)
				{
					Text("DetailTitle", (Transform)(object)content, 0f, y, width, 28f, 19f, Gold, p.PickName(growthPick2.Id) + " · 为什么推荐");
					y += 34f;
					Text("Reason", (Transform)(object)content, 0f, y, width, 90f, 15f, Paper, AdvicePresentation.StackTip(growthPick2) + " · " + growthPick2.Basis + "\n" + growthPick2.Reason, wrap: true);
					y += 96f;
					Text("Marginal", (Transform)(object)content, 0f, y, width, 88f, 14f, Muted, growthPick2.Marginal, wrap: true);
					y += 94f;
					string id2 = growthPick2.Id;
					Button("本局忽略这件", (Transform)(object)content, 0f, y, 160f, 32f, delegate
					{
						p.ignoredItems.Add(id2);
						p.lastIgnored = id2;
						p.Refresh();
					});
					if (p.lastIgnored != "")
					{
						Button("撤销上次忽略", (Transform)(object)content, 172f, y, 160f, 32f, delegate
						{
							p.ignoredItems.Remove(p.lastIgnored);
							p.lastIgnored = "";
							p.Refresh();
						});
					}
					y += 48f;
				}
				if (p.recentChanges.Count > 0)
				{
					Text("Recent", (Transform)(object)content, 0f, y, width, 42f, 13f, Muted, p.recentChanges.Last(), wrap: true);
					y += 50f;
				}
				Heading("其他成长候选");
				foreach (GrowthPick item in p.growthPicks.Where((GrowthPick g) => g.Actionable).Take(24))
				{
					ItemDef def2 = p.Def(item.Id);
					Icon((Transform)(object)content, 0f, y, 42f, () => p.ItemIcon(def2));
					Text("Item", (Transform)(object)content, 56f, y, width - 210f, 24f, 16f, Paper, p.PickName(item.Id) + " · " + item.Category);
					Text("ItemHint", (Transform)(object)content, 56f, y + 25f, width - 210f, 20f, 13f, Muted, "已有 " + item.Have + " / 参考 " + item.SoftGoal + " · " + item.State);
					string id3 = item.Id;
					Button("详情", (Transform)(object)content, width - 80f, y + 5f, 80f, 32f, delegate
					{
						p.selectedGrowth = id3;
					});
					y += 60f;
				}
			}

			private void Skills()
			{
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_0195: Unknown result type (might be due to invalid IL or missing references)
				Heading("当前技能与依据", p.plan?.Confidence ?? "选择角色后自动读取。");
				if (p.plan != null)
				{
					Text("Play", (Transform)(object)content, 0f, y, width, 74f, 16f, Paper, p.plan.Play, wrap: true);
					y += 86f;
				}
				SkillEvidence[] skills = p.skills;
				foreach (SkillEvidence skillEvidence in skills)
				{
					Text("Skill", (Transform)(object)content, 0f, y, width, 30f, 19f, Gold, skillEvidence.Slot + " · " + skillEvidence.Name);
					y += 34f;
					Text("Stats", (Transform)(object)content, 0f, y, width, 22f, 13f, Muted, "基础冷却 " + skillEvidence.Cooldown.ToString("0.##") + " 秒 · 基础充能 " + skillEvidence.Stock);
					y += 28f;
					Text("Description", (Transform)(object)content, 0f, y, width, 82f, 16f, Paper, skillEvidence.Description, wrap: true);
					y += 90f;
				}
				Button("导出技能及成长评分报告", (Transform)(object)content, 0f, y, 250f, 36f, p.ExportEvidence);
				y += 48f;
			}

			private void Toggle(string title, float x, float top, float w, Func<bool> read, Action<bool> write)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				Text("ToggleLabel", (Transform)(object)content, x, top, w - 100f, 34f, 15f, Paper, title);
				Button(read() ? "已开启" : "已关闭", (Transform)(object)content, x + w - 90f, top, 90f, 32f, delegate
				{
					write(!read());
				}, read());
			}

			private void Slider(string title, float x, float top, float w, float min, float max, Func<float> read, Action<float> write, string format = "0.00")
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: 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_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				TextMeshProUGUI label = Text("SliderLabel", (Transform)(object)content, x, top, w, 24f, 14f, Muted, title + "  " + read().ToString(format));
				RectTransform val = Box("Slider", (Transform)(object)content);
				Place(val, x, top + 29f, w, 28f);
				Slider obj = ((Component)val).gameObject.AddComponent<Slider>();
				Navigation navigation = default(Navigation);
				((Navigation)(ref navigation)).mode = (Mode)0;
				((Selectable)obj).navigation = navigation;
				((Graphic)Panel("Track", (Transform)(object)val, 0f, 12f, w, 3f, new Color(0.2f, 0.22f, 0.23f))).raycastTarget = true;
				Image val2 = Panel("Fill", (Transform)(object)val, 0f, 12f, w, 3f, Gold);
				Image val3 = Panel("Handle", (Transform)(object)val, 0f, 6f, 12f, 16f, Paper);
				((Graphic)val3).raycastTarget = true;
				obj.fillRect = ((Graphic)val2).rectTransform;
				obj.handleRect = ((Graphic)val3).rectTransform;
				((Selectable)obj).targetGraphic = (Graphic)(object)val3;
				obj.minValue = min;
				obj.maxValue = max;
				obj.value = read();
				((UnityEvent<float>)(object)obj.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
				{
					write(value);
					((TMP_Text)label).text = title + "  " + value.ToString(format);
				});
			}

			private void Settings()
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0216: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0688: Unknown result type (might be due to invalid IL or missing references)
				Heading("显示与操作", "设置按组排列;滑块可实时调整,关闭菜单时保存。");
				float num = y;
				float w = 480f;
				Text("Group", (Transform)(object)content, 0f, num, w, 28f, 19f, Gold, "界面显示");
				Text("Group", (Transform)(object)content, 530f, num, w, 28f, 19f, Gold, "推荐HUD");
				y = num + 40f;
				Toggle("局内推荐HUD", 0f, y, w, () => p.showHud.Value, delegate(bool v)
				{
					p.showHud.Value = v;
				});
				Toggle("主动装备建议", 530f, y, w, () => p.hudShowEquipment.Value, delegate(bool v)
				{
					p.hudShowEquipment.Value = v;
				});
				y += 48f;
				Toggle("统率推荐高亮", 0f, y, w, () => p.enhanceCommand.Value, delegate(bool v)
				{
					p.enhanceCommand.Value = v;
				});
				Toggle("增加红装一行", 530f, y, w, () => p.hudShowRed.Value, delegate(bool v)
				{
					p.hudShowRed.Value = v;
				});
				y += 58f;
				Slider("菜单大小", 0f, y, w, 0.85f, 1.25f, () => p.interfaceScale.Value, delegate(float v)
				{
					p.interfaceScale.Value = v;
				});
				Slider("HUD大小", 530f, y, w, 0.7f, 1.5f, () => p.nativeHudScale.Value, delegate(float v)
				{
					p.nativeHudScale.Value = v;
				});
				y += 78f;
				Text("NativePicker", (Transform)(object)content, 0f, y, w, 58f, 14f, Muted, "统率使用原版界面与鼠标\nS 首选 · A 优先 · B 可选 · C 备选", wrap: true);
				Slider("背景不透明度", 530f, y, w, 0f, 0.6f, () => p.hudOpacity.Value, delegate(float v)
				{
					p.hudOpacity.Value = v;
				});
				y += 78f;
				Toggle("自动避让队友与无人机", 0f, y, 480f, () => p.hudAutoDock.Value, delegate(bool v)
				{
					p.hudAutoDock.Value = v;
				});
				Text("DockHelp", (Transform)(object)content, 530f, y, 480f, 40f, 13f, Muted, "自动模式跟随左侧HUD;关闭后使用下方手动位置。", wrap: true);
				y += 52f;
				Slider("HUD横向位置", 0f, y, w, 0f, 1f, () => p.hudX.Value, delegate(float v)
				{
					p.hudX.Value = v;
				});
				Slider("HUD纵向位置", 530f, y, w, 0f, 1f, () => p.hudY.Value, delegate(float v)
				{
					p.hudY.Value = v;
				});
				y += 84f;
				Button("保存并预览HUD", (Transform)(object)content, 0f, y, 220f, 36f, delegate
				{
					((BaseUnityPlugin)p).Config.Save();
					p.SetOpen(value: false);
				});
				Button("完全透明", (Transform)(object)content, 234f, y, 150f, 36f, delegate
				{
					p.hudOpacity.Value = 0f;
				});
				Button("恢复HUD默认", (Transform)(object)content, 530f, y, 220f, 36f, delegate
				{
					p.hudAutoDock.Value = true;
					p.hudOpacity.Value = 0.1f;
					p.nativeHudScale.Value = 0.85f;
					p.hudX.Value = 0.015f;
					p.hudY.Value = 0.21f;
					p.hudShowEquipment.Value = false;
					p.showHud.Value = true;
				});
				y += 56f;
				Button("清空本局忽略(" + p.ignoredItems.Count + ")", (Transform)(object)content, 0f, y, 260f, 36f, delegate
				{
					p.ignoredItems.Clear();
					p.lastIgnored = "";
					p.Refresh();
				});
				Button("重新加载图标", (Transform)(object)content, 530f, y, 220f, 36f, delegate
				{
					p.iconAssets.Dispose();
					p.iconAssets = new IconAssets(delegate(string s)
					{
						((BaseUnityPlugin)p).Logger.LogWarning((object)s);
					});
				});
				y += 58f;
				Text("HelpGroup", (Transform)(object)content, 0f, y, width, 28f, 19f, Gold, "新手引导与界面恢复");
				y += 40f;
				Toggle("显示新手简明提示", 0f, y, 480f, () => p.beginnerHelp.Value, delegate(bool v)
				{
					p.beginnerHelp.Value = v;
				});
				Toggle("统率展开计算细节", 530f, y, 480f, () => p.detailInPicker.Value, delegate(bool v)
				{
					p.detailInPicker.Value = v;
				});
				y += 52f;
				Text("Health", (Transform)(object)content, 0f, y, width, 24f, 13f, Muted, p.uiHealth);
				y += 34f;
				Button("导出界面与掉落诊断", (Transform)(object)content, 0f, y, 240f, 36f, p.ExportDiagnostics);
				Button("清理并重建助手界面", (Transform)(object)content, 530f, y, 260f, 36f, p.RebuildAssistantUi);
				y += 54f;
				Text("InputHelp", (Transform)(object)content, 0f, y, width, 76f, 14f, Muted, "打开助手时会隔离后方菜单和角色输入。Esc只关闭当前助手,不会顺带操作暂停菜单;关闭后恢复此前输入状态。\nHUD默认只保留白、绿两条建议,主动装备和红装可以按需开启。", wrap: true);
				y += 90f;
			}

			private void Routes()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0184: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_023e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0281: Unknown result type (might be due to invalid IL or missing references)
				Text("RouteTitle", (Transform)(object)content, 0f, y, width, 28f, 20f, Gold, "这个角色的流派路线");
				y += 34f;
				Text("RouteState", (Transform)(object)content, 0f, y, 760f, 34f, 14f, Muted, ((p.style.Value == 0) ? "按技能自动推荐" : "已固定此角色方向") + " · " + (p.plan?.Name ?? "等待读取") + ";切换只改变建议,保留背包。");
				Button("按技能自动", (Transform)(object)content, 810f, y, 190f, 32f, delegate
				{
					p.SelectRoute(0);
				}, p.style.Value == 0);
				y += 48f;
				foreach (RouteOption routeOption in p.routeOptions)
				{
					RouteOption route = routeOption;
					Panel("Route", (Transform)(object)content, 0f, y, width, 112f, new Color(0.1f, 0.12f, 0.13f));
					Text("Name", (Transform)(object)content, 14f, y + 8f, 760f, 26f, 18f, Paper, route.Name + ((p.plan != null && p.plan.Name == route.Name) ? " · 当前" : ""));
					Text("Condition", (Transform)(object)content, 14f, y + 38f, 760f, 30f, 14f, Muted, route.Condition);
					Text("Support", (Transform)(object)content, 14f, y + 72f, 760f, 26f, 14f, Muted, route.Reason);
					Button((p.style.Value == route.Style) ? "已固定" : "选择并记住", (Transform)(object)content, 810f, y + 37f, 184f, 34f, delegate
					{
						p.SelectRoute(route.Style);
					}, p.style.Value == route.Style);
					y += 124f;
				}
			}

			private void Loadout()
			{
				//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0239: Unknown result type (might be due to invalid IL or missing references)
				//IL_0530: Unknown result type (might be due to invalid IL or missing references)
				//IL_057a: Unknown result type (might be due to invalid IL or missing references)
				//IL_076b: Unknown result type (might be due to invalid IL or missing references)
				Heading("配装与体验", "正常模式只提供建议;体验与测试操作需要确认,并且只作用于自己。");
				string[] array = new string[3] { "正常:只推荐", "体验:确认补齐", "测试:本局自动" };
				for (int i = 0; i < 3; i++)
				{
					int n = i;
					Button(array[i], (Transform)(object)content, i * 258, y, 246f, 36f, delegate
					{
						p.mode = n;
						p.autoArmed = false;
						p.confirm = false;
					}, p.mode == i);
				}
				y += 52f;
				Routes();
				for (int num = 1; num <= 3; num++)
				{
					int n2 = num;
					Button((new string[3] { "起步", "进阶", "成型练习" })[num - 1], (Transform)(object)content, (num - 1) * 160, y, 150f, 32f, delegate
					{
						p.scale.Value = n2;
						p.autoArmed = false;
						p.Refresh();
					}, p.scale.Value == num);
				}
				y += 48f;
				if (p.plan == null)
				{
					Text("Empty", (Transform)(object)content, 0f, y, width, 40f, 16f, Muted, "等待角色读取。");
					y += 50f;
					return;
				}
				EquipmentDef equipment = p.SuggestedEquipment();
				if (Object.op_Implicit((Object)(object)equipment))
				{
					Icon((Transform)(object)content, 0f, y, 44f, () => p.EquipmentIcon(equipment));
				}
				Text("Equip", (Transform)(object)content, 58f, y, width - 60f, 44f, 16f, Paper, "主动装备建议:" + (Object.op_Implicit((Object)(object)equipment) ? Chinese(equipment.nameToken) : "未知"));
				y += 56f;
				string[] array2 = new string[7] { "自动", "治疗", "导弹", "聚怪", "护甲", "雷电", "飞行" };
				for (int num2 = 0; num2 < 7; num2++)
				{
					int n3 = num2;
					Button(array2[num2], (Transform)(object)content, num2 * 110, y, 100f, 30f, delegate
					{
						p.equipmentChoice.Value = n3;
						p.autoArmed = false;
					}, p.equipmentChoice.Value == num2);
				}
				y += 44f;
				Toggle("应用时替换当前主动装备", 0f, y, 500f, () => p.applyEquipment, delegate(bool v)
				{
					p.applyEquipment = v;
					p.autoArmed = false;
				});
				y += 48f;
				bool interactable = p.mode != 0 && Object.op_Implicit((Object)(object)p.currentBody) && Object.op_Implicit((Object)(object)Run.instance) && NetworkServer.active;
				((Selectable)Button((p.mode == 2 && p.autoArmed) ? "停止本局自动配置" : "预览并应用配装", (Transform)(object)content, 0f, y, 250f, 38f, delegate
				{
					if (p.mode == 2 && p.autoArmed)
					{
						p.autoArmed = false;
					}
					else
					{
						Confirm();
					}
				})).interactable = interactable;
				Button("保存调配", (Transform)(object)content, 268f, y, 150f, 38f, delegate
				{
					((BaseUnityPlugin)p).Config.Save();
				});
				Button("恢复默认数量", (Transform)(object)content, 436f, y, 190f, 38f, delegate
				{
					foreach (ItemAdvice item2 in p.plan.Items)
					{
						p.CountEntry(item2).Value = item2.Count;
					}
					p.autoArmed = false;
					p.Refresh();
				});
				y += 56f;
				foreach (ItemAdvice item3 in p.plan.Items)
				{
					ItemDef def = p.Def(item3.Id);
					Icon((Transform)(object)content, 0f, y, 44f, () => p.ItemIcon(def));
					Text("Item", (Transform)(object)content, 58f, y, 650f, 24f, 16f, Paper, p.PickName(item3.Id));
					Text("Count", (Transform)(object)content, 58f, y + 24f, 650f, 22f, 13f, Muted, "已有 " + p.Have(item3.Id) + " · 目标 " + p.Target(item3) + " · " + (p.Blocked(def) ?? "只补不足数量"));
					ItemAdvice item = item3;
					Button("−", (Transform)(object)content, 774f, y + 6f, 42f, 32f, delegate
					{
						int num3 = ((!Input.GetKey((KeyCode)304)) ? 1 : 5);
						p.CountEntry(item).Value = Mathf.Max(0, p.Target(item) - num3);
						p.autoArmed = false;
						p.Refresh();
					});
					NumberField((Transform)(object)content, 824f, y + 5f, 70f, 34f, p.Target(item).ToString(), delegate(string text)
					{
						if (int.TryParse(text, out var result))
						{
							p.CountEntry(item).Value = Mathf.Clamp(result, 0, 100);
							p.autoArmed = false;
							p.Refresh();
						}
					});
					Button("+", (Transform)(object)content, 902f, y + 6f, 42f, 32f, delegate
					{
						int num3 = ((!Input.GetKey((KeyCode)304)) ? 1 : 5);
						p.CountEntry(item).Value = Mathf.Min(100, p.Target(item) + num3);
						p.autoArmed = false;
						p.Refresh();
					});
					y += 60f;
				}
				Heading("加入其他物品", "输入中文名或内部名称后回车搜索。");
				NumberField((Transform)(object)content, 0f, y, 700f, 38f, p.search, delegate(string value)
				{
					p.search = value;
				}, numeric: false);
				y += 50f;
				if (string.IsNullOrWhiteSpace(p.search))
				{
					return;
				}
				foreach (ItemDef item4 in ((IEnumerable<ItemDef>)(object)ItemCatalog.allItemDefs).Where((ItemDef d) => Object.op_Implicit((Object)(object)d) && !d.hidden && (int)d.tier != 5 && (Chinese(d.nameToken).IndexOf(p.search, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)d).name.IndexOf(p.search, StringComparison.OrdinalIgnoreCase) >= 0)).Take(12))
				{
					ItemDef chosen = item4;
					Button("加入 · " + Chinese(item4.nameToken), (Transform)(object)content, 0f, y, 700f, 34f, delegate
					{
						ConfigEntry<string> obj = ((BaseUnityPlugin)p).Config.Bind<string>(p.CountSection, "自选物品列表", "", "手动加入的物品内部名称,以逗号分隔");
						List<string> list = (from s in obj.Value.Split(',')
							where !string.IsNullOrWhiteSpace(s)
							select s).ToList();
						if (!list.Contains(((Object)chosen).name))
						{
							list.Add(((Object)chosen).name);
						}
						obj.Value = string.Join(",", list);
						p.CountEntry(new ItemAdvice(((Object)chosen).name, 1, 50, "手动加入")).Value = 1;
						p.autoArmed = false;
						p.Refresh();
					});
					y += 42f;
				}
			}

			private void NumberField(Transform parent, float x, float top, float w, float h, string initial, Action<string> save, bool numeric = true)
			{
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				Image val = Panel("Input", parent, x, top, w, h, new Color(0.08f, 0.09f, 0.1f));
				((Graphic)val).raycastTarget = true;
				TMP_InputField obj = ((Component)val).gameObject.AddComponent<TMP_InputField>();
				TextMeshProUGUI textComponent = Text("Text", ((Component)val).transform, 8f, 0f, w - 16f, h, 16f, Paper, initial);
				obj.textComponent = (TMP_Text)(object)textComponent;
				obj.textViewport = ((Graphic)val).rectTransform;
				obj.contentType = (ContentType)(numeric ? 2 : 0);
				obj.characterLimit = (numeric ? 3 : 80);
				obj.customCaretColor = true;
				obj.caretColor = Paper;
				obj.selectionColor = new Color(0.7f, 0.55f, 0.2f, 0.3f);
				obj.text = initial;
				string section = p.EditContext;
				((UnityEvent<string>)(object)obj.onEndEdit).AddListener((UnityAction<string>)delegate(string value)
				{
					p.Defer(delegate
					{
						if (!numeric || (p.plan != null && p.EditContext == section))
						{
							save(value);
						}
						dirty = true;
					});
				});
			}

			private void Confirm()
			{
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0106: Unknown result type (might be due to invalid IL or missing references)
				//IL_0170: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)confirmation))
				{
					Object.Destroy((Object)(object)confirmation);
				}
				p.Refresh();
				if (p.plan == null || !Object.op_Implicit((Object)(object)p.currentBody) || !Object.op_Implicit((Object)(object)Run.instance) || p.mode == 0 || !NetworkServer.active)
				{
					return;
				}
				p.confirm = true;
				p.confirmSignature = p.Signature;
				Image val = Panel("ConfirmBlocker", (Transform)(object)shell, 0f, 0f, 1280f, 760f, new Color(0f, 0f, 0f, 0.75f));
				((Graphic)val).raycastTarget = true;
				confirmation = ((Component)val).gameObject;
				Image val2 = Panel("Confirm", ((Component)val).transform, 360f, 245f, 560f, 250f, new Color(0.09f, 0.105f, 0.11f));
				((Graphic)val2).raycastTarget = true;
				int num = p.plan.Items.Where((ItemAdvice i) => p.Blocked(p.Def(i.Id)) == null).Sum((ItemAdvice i) => BuildLogic.Missing(p.Target(i), p.Have(i.Id)));
				Text("Title", ((Component)val2).transform, 22f, 18f, 516f, 32f, 22f, Paper, "确认修改当前配装");
				Text("Message", ((Component)val2).transform, 22f, 62f, 516f, 100f, 16f, Paper, "将为自己补充 " + num + " 件物品。\n" + (p.applyEquipment ? "将替换当前槽位主动装备。" : "保留当前主动装备。") + ((p.mode == 2) ? "\n同时启用本局角色生成、换关后的自动补齐。" : ""), wrap: true);
				Button("确认应用", ((Component)val2).transform, 22f, 185f, 245f, 40f, delegate
				{
					if (p.confirm && p.Signature == p.confirmSignature && p.ApplyPlan(p.confirmSignature) && p.mode == 2 && Object.op_Implicit((Object)(object)p.currentBody) && Object.op_Implicit((Object)(object)Run.instance) && NetworkServer.active)
					{
						p.autoRun = Run.instance;
						p.autoBody = ((Object)p.currentBody).GetInstanceID();
						p.autoStage = Run.instance.stageClearCount;
						p.autoArmed = true;
					}
					CancelConfirmation();
				});
				Button("取消", ((Component)val2).transform, 280f, 185f, 258f, 40f, delegate
				{
					CancelConfirmation();
				});
			}

			public void Dispose()
			{
				if (Object.op_Implicit((Object)(object)root))
				{
					Object.Destroy((Object)(object)root);
				}
			}
		}

		private AdvisorPickerBridge pickerBridge;

		private bool pickerErrorLogged;

		private Run observedRun;

		private readonly DropLedger dropLedger = new DropLedger();

		private DateTime dropObservationSince;

		private bool dropObservationFailed;

		private IconAssets iconAssets;

		private readonly HashSet<NativeAdviceHud> nativeHuds = new HashSet<NativeAdviceHud>();

		private bool nativeHudErrorLogged;

		private NativeMenu menu;

		private readonly ModalInputLease menuInput = new ModalInputLease();

		private int modalReleaseFrame = -1;

		private bool modalHadDesired;

		private List<RouteOption> routeOptions = new List<RouteOption>();

		private RouteOption transition;

		private readonly RecommendationMemory recommendationMemory = new RecommendationMemory();

		private ConfigEntry<bool> beginnerHelp;

		private ConfigEntry<bool> detailInPicker;

		private ConfigEntry<bool> oldRouteMigrated;

		private readonly Queue<string> uiIncidents = new Queue<string>();

		private int recoveries;

		private float nextUiHealth;

		private string uiHealth = "等待首次界面检查";

		private bool analysisErrorLogged;

		internal static Plugin Instance;

		private Harmony harmony;

		private ConfigEntry<KeyCode> key;

		private ConfigEntry<int> style;

		private ConfigEntry<int> scale;

		private ConfigEntry<int> iconSize;

		private ConfigEntry<int> equipmentChoice;

		private ConfigEntry<int> growthFocus;

		private ConfigEntry<bool> enhanceCommand;

		private ConfigEntry<bool> showHud;

		private ConfigEntry<float> interfaceScale;

		private ConfigEntry<float> hudX;

		private ConfigEntry<float> hudY;

		private ConfigEntry<float> nativeHudScale;

		private ConfigEntry<float> hudOpacity;

		private ConfigEntry<bool> hudShowRed;

		private ConfigEntry<bool> hudShowEquipment;

		private ConfigEntry<bool> hudAutoDock;

		private int mode;

		private bool open;

		private bool autoArmed;

		private float nextScan;

		private int autoBody;

		private int autoStage = -1;

		private Run autoRun;

		private CharacterBody currentBody;

		private string bodyId = "";

		private string bodyLabel = "尚未进入对局";

		private SkillEvidence[] skills = new SkillEvidence[0];

		private Dictionary<string, int> inventory = new Dictionary<string, int>();

		private Dictionary<string, int> effectiveInventory = new Dictionary<string, int>();

		private List<GrowthPick> growthPicks = new List<GrowthPick>();

		private readonly HashSet<string> ignoredItems = new HashSet<string>();

		private readonly Queue<string> recentChanges = new Queue<string>();

		private readonly Dictionary<Type, string> constantCache = new Dictionary<Type, string>();

		private string detection = "等待检测角色";

		private string lastDetectedSkills = "";

		private bool refreshDirty = true;

		private bool lobbyPreview;

		private float nextAudit;

		private int recommendationVersion;

		private readonly Dictionary<string, ItemDef> defs = new Dictionary<string, ItemDef>(StringComparer.OrdinalIgnoreCase);

		private readonly Dictionary<string, ConfigEntry<int>> customCounts = new Dictionary<string, ConfigEntry<int>>();

		private BuildPlan plan;

		private string status = "正常模式只提供建议。F2 打开或关闭助手。";

		private string search = "";

		private bool confirm;

		private bool applyEquipment;

		private string confirmSignature;

		private readonly Queue<Action> pending = new Queue<Action>();

		private static readonly Dictionary<string, string> chineseTextCache = new Dictionary<string, string>();

		private int workspace;

		private string selectedGrowth = "";

		private string lastIgnored = "";

		internal int RecommendationVersion => recommendationVersion;

		private bool CommandVisible
		{
			get
			{
				if (Object.op_Implicit((Object)(object)pickerBridge) && pickerBridge.IsCommand)
				{
					return ((Behaviour)pickerBridge).isActiveAndEnabled;
				}
				return false;
			}
		}

		internal bool NativeHudAutoDock => hudAutoDock.Value;

		internal float NativeHudX => hudX.Value;

		internal float NativeHudY => hudY.Value;

		internal float NativeHudScale => nativeHudScale.Value;

		internal float NativeHudOpacity => hudOpacity.Value;

		internal string NativeHudRole => bodyLabel;

		internal bool OwnsModalInput
		{
			get
			{
				if (((Behaviour)this).isActiveAndEnabled && !CommandVisible)
				{
					if (!open)
					{
						return Time.frameCount <= modalReleaseFrame;
					}
					return true;
				}
				return false;
			}
		}

		private string EditContext => CountSection + "/" + lastDetectedSkills + "/" + (Object.op_Implicit((Object)(object)currentBody) ? ((Object)currentBody).GetInstanceID() : 0);

		private string CountSection => "配装." + bodyId + "." + style.Value + "." + scale.Value;

		private string Signature
		{
			get
			{
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Unknown result type (might be due to invalid IL or missing references)
				//IL_019f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				string context = bodyId + "/" + style.Value + "/" + scale.Value + "/" + mode + "/" + equipmentChoice.Value + "/" + applyEquipment + "/" + (Object.op_Implicit((Object)(object)currentBody) ? ((Object)currentBody).GetInstanceID() : 0) + "/" + (Object.op_Implicit((Object)(object)Run.instance) ? ((Object)Run.instance).GetInstanceID() : 0) + "/" + lastDetectedSkills + "/" + (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.stageClearCount : 0) + "/" + ((applyEquipment && Object.op_Implicit((Object)(object)currentBody) && Object.op_Implicit((Object)(object)currentBody.inventory)) ? (((object)currentBody.inventory.currentEquipmentIndex/*cast due to .constrained prefix*/).ToString() + "@" + ((object)currentBody.inventory.activeEquipmentLocation/*cast due to .constrained prefix*/).ToString()) : "");
				IEnumerable<KeyValuePair<string, int>> targets;
				if (plan != null)
				{
					targets = plan.Items.Select((ItemAdvice i) => new KeyValuePair<string, int>(i.Id, Target(i)));
				}
				else
				{
					IEnumerable<KeyValuePair<string, int>> enumerable = new KeyValuePair<string, int>[0];
					targets = enumerable;
				}
				return PlanStamp.Create(context, targets, inventory);
			}
		}

		internal void RegisterPicker(AdvisorPickerBridge bridge)
		{
			if (bridge.IsCommand)
			{
				pickerBridge = bridge;
			}
		}

		internal bool ShouldEnhance(AdvisorPickerBridge bridge)
		{
			if (((Behaviour)this).isActiveAndEnabled && enhanceCommand.Value && Object.op_Implicit((Object)(object)bridge) && bridge.IsCommand && ((Behaviour)bridge).isActiveAndEnabled)
			{
				return bridge.Options != null;
			}
			return false;
		}

		private GrowthPick GrowthForPickup(PickupDef pickup)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			ItemDef val = ((pickup == null) ? null : ItemCatalog.GetItemDef(pickup.itemIndex));
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return Growth(((Object)val).name);
		}

		internal double PickerScore(PickupDef pickup)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (plan == null)
			{
				return 0.0;
			}
			GrowthPick growthPick = GrowthForPickup(pickup);
			if (growthPick != null)
			{
				if (!growthPick.Actionable || !PriorityLogic.Valid(growthPick.Score))
				{
					return 0.0;
				}
				return growthPick.Score;
			}
			if (pickup == null || (int)pickup.equipmentIndex == -1)
			{
				return 0.0;
			}
			if (Object.op_Implicit((Object)(object)currentBody) && Object.op_Implicit((Object)(object)currentBody.inventory) && currentBody.inventory.currentEquipmentIndex == pickup.equipmentIndex)
			{
				return 0.0;
			}
			EquipmentDef val = SuggestedEquipment();
			return (Object.op_Implicit((Object)(object)val) && val.equipmentIndex == pickup.equipmentIndex) ? 50 : 0;
		}

		internal string PickerReason(PickupDef pickup, int level, double best)
		{
			if (level <= 0)
			{
				return "";
			}
			GrowthPick growthPick = GrowthForPickup(pickup);
			string text = "流派推荐 · " + PriorityLogic.Label(level) + "\n";
			if (growthPick == null)
			{
				return text + "符合当前流派的主动装备建议;是否替换仍由你选择。";
			}
			return text + AdvicePresentation.Strength(best) + "\n已有 " + growthPick.Have + " / 软参考 " + growthPick.SoftGoal + " · " + growthPick.Category + " · " + growthPick.Basis + "\n" + AdvicePresentation.StackTip(growthPick) + "。" + AdvicePresentation.ShortReason(growthPick) + (detailInPicker.Value ? ("\n" + growthPick.Reason + "\n" + growthPick.Marginal) : "") + "\n等级是本次相对优先级;F2可查看联动与计算条件。";
		}

		internal void PickerFailure(Exception ex)
		{
			if (!pickerErrorLogged)
			{
				pickerErrorLogged = true;
				RecordUiIncident("统率标记已回退原版", ex);
			}
		}

		private void EnsureDropRun()
		{
			if (observedRun != Run.instance)
			{
				observedRun = Run.instance;
				dropLedger.Reset();
				dropObservationSince = DateTime.UtcNow;
				dropObservationFailed = false;
			}
		}

		internal unsafe void ObserveDrop(UniquePickup state, bool cube)
		{
			//IL_0023: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!((Behaviour)this).isActiveAndEnabled || !NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance))
			{
				return;
			}
			try
			{
				EnsureDropRun();
				PickupIndex pickupIndex = state.pickupIndex;
				PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
				if (pickupDef == null)
				{
					dropLedger.Invalid();
					return;
				}
				ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
				string text = (Object.op_Implicit((Object)(object)itemDef) ? ((object)itemDef.tier/*cast due to .constrained prefix*/).ToString() : "Equipment/Other");
				string text2 = (cube ? "统率方块" : "掉落球");
				dropLedger.Record(text2, text, "关卡" + (Run.instance.stageClearCount + 1) + " / " + text2 + " / " + text + " / " + (Object.op_Implicit((Object)(object)itemDef) ? ((Object)itemDef).name : ((object)(*(PickupIndex*)(&pickupIndex))/*cast due to .constrained prefix*/).ToString()) + " / 升级标记=" + state.upgradeValue + " / 临时=" + ((UniquePickup)(ref state)).isTempItem + " / 忽略神器替换=" + state.ignoreArtifactBasedPickupReplacements);
			}
			catch (Exception ex)
			{
				dropLedger.Fail(ex.GetType().Name + ":" + ex.Message);
				if (!dropObservationFailed)
				{
					dropObservationFailed = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)("掉落只读诊断不可用:" + ex.Message));
				}
			}
		}

		private void AppendDropDiagnostics(StringBuilder report)
		{
			EnsureDropRun();
			report.AppendLine("--- 掉落只读诊断 ---");
			report.AppendLine("模式:" + mode + "(0正常,1体验,2测试);补齐配装不计入世界掉落。");
			report.AppendLine("仅统计本Mod启动后、当前主机观察到的掉落球和统率方块。两类为同一掉落的不同阶段,请勿相加;客户端不能代表主机掉落总数。直接生成、交换、发放物品可能不经过掉落球。统计不能证明概率正确或屏幕渲染成功。");
			if (!Object.op_Implicit((Object)(object)Run.instance))
			{
				report.AppendLine("当前不在对局。");
				return;
			}
			report.AppendLine("主机:" + NetworkServer.active + ";关卡:" + (Run.instance.stageClearCount + 1));
			report.AppendLine("当前可用池数量:白=" + (Run.instance.availableTier1DropList?.Count.ToString() ?? "尚未建立") + ",绿=" + (Run.instance.availableTier2DropList?.Count.ToString() ?? "尚未建立") + ",红=" + (Run.instance.availableTier3DropList?.Count.ToString() ?? "尚未建立"));
			report.AppendLine("本局观察开始(UTC):" + dropObservationSince.ToString("O") + ";未分类事件:" + dropLedger.Unclassified);
			report.AppendLine("诊断状态:" + (dropLedger.Failure ?? "尚未记录到异常") + ";无异常记录不能证明事件覆盖完整。");
			report.AppendLine("按源物品品质归类,升级/临时标记见事件明细;不据此保证最终统率选项的品质。");
			RunArtifactManager instance = RunArtifactManager.instance;
			int num = 0;
			while (Object.op_Implicit((Object)(object)instance) && num < ArtifactCatalog.artifactCount)
			{
				ArtifactDef artifactDef = ArtifactCatalog.GetArtifactDef((ArtifactIndex)num);
				if (Object.op_Implicit((Object)(object)artifactDef) && instance.IsArtifactEnabled(artifactDef))
				{
					report.AppendLine("已启用神器:" + Chinese(artifactDef.nameToken) + " / " + artifactDef.cachedName);
				}
				num++;
			}
			string[] array = new string[6] { "掉落球 / Tier1", "统率方块 / Tier1", "掉落球 / Tier2", "统率方块 / Tier2", "掉落球 / Tier3", "统率方块 / Tier3" };
			foreach (string text in array)
			{
				report.AppendLine(text + " = " + dropLedger.Count(text));
			}
			foreach (KeyValuePair<string, int> count in dropLedger.Counts)
			{
				if (!count.Key.EndsWith(" / Tier1") && !count.Key.EndsWith(" / Tier2") && !count.Key.EndsWith(" / Tier3"))
				{
					report.AppendLine(count.Key + " = " + count.Value);
				}
			}
			report.AppendLine("最近最多64条事件:");
			foreach (string item in dropLedger.History)
			{
				report.AppendLine(item);
			}
		}

		private Sprite ItemIcon(ItemDef def)
		{
			return iconAssets?.Item(def);
		}

		private Sprite EquipmentIcon(EquipmentDef def)
		{
			return iconAssets?.Equipment(def);
		}

		internal void AttachNativeHud(HUD hud)
		{
			if (Object.op_Implicit((Object)(object)hud))
			{
				NativeAdviceHud nativeAdviceHud = ((Component)hud).GetComponent<NativeAdviceHud>();
				if (!Object.op_Implicit((Object)(object)nativeAdviceHud))
				{
					nativeAdviceHud = ((Component)hud).gameObject.AddComponent<NativeAdviceHud>();
				}
				nativeAdviceHud.Initialize(hud);
				nativeHuds.Add(nativeAdviceHud);
			}
		}

		internal void ForgetNativeHud(NativeAdviceHud view)
		{
			nativeHuds.Remove(view);
		}

		internal void NativeHudFailure(Exception ex)
		{
			if (!nativeHudErrorLogged)
			{
				nativeHudErrorLogged = true;
				RecordUiIncident("推荐HUD已隐藏,F2仍可使用", ex);
			}
		}

		internal bool NativeHudVisible(HUD hud)
		{
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			if (((Behaviour)this).isActiveAndEnabled && showHud.Value && Object.op_Implicit((Object)(object)currentBody) && plan != null && !open && !CommandVisible && Object.op_Implicit((Object)(object)hud) && hud.localUserViewer == firstLocalUser && (Object)(object)hud.targetBodyObject == (Object)(object)((Component)currentBody).gameObject)
			{
				if (Object.op_Implicit((Object)(object)hud.scoreboardPanel))
				{
					return !hud.scoreboardPanel.activeSelf;
				}
				return true;
			}
			return false;
		}

		internal List<NativeHudItem> NativeHudRows()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			List<NativeHudItem> list = new List<NativeHudItem>();
			for (int i = 1; i <= (hudShowRed.Value ? 3 : 2); i++)
			{
				GrowthPick growthPick = BestForTier(i);
				if (growthPick != null)
				{
					ItemDef val = Def(growthPick.Id);
					if (Object.op_Implicit((Object)(object)val))
					{
						list.Add(new NativeHudItem
						{
							Icon = ItemIcon(val),
							IconState = (iconAssets.ItemFailed(val) ? "?" : "…"),
							Name = Chinese(val.nameToken),
							Color = Color32.op_Implicit(ColorCatalog.GetColor(val.colorIndex)),
							Detail = growthPick.Category + " · " + ((growthPick.Have == 0) ? "先拿1件" : ((growthPick.Have >= growthPick.SoftGoal) ? "已有基础,比较其他短板" : ("已有 " + growthPick.Have + " / 参考 " + growthPick.SoftGoal)))
						});
					}
				}
			}
			if (hudShowEquipment.Value)
			{
				EquipmentDef val2 = SuggestedEquipment();
				if (Object.op_Implicit((Object)(object)val2))
				{
					bool flag = Object.op_Implicit((Object)(object)currentBody) && Object.op_Implicit((Object)(object)currentBody.inventory) && currentBody.inventory.currentEquipmentIndex == val2.equipmentIndex;
					list.Add(new NativeHudItem
					{
						Icon = EquipmentIcon(val2),
						IconState = (iconAssets.EquipmentFailed(val2) ? "?" : "…"),
						Name = Chinese(val2.nameToken),
						Color = new Color(1f, 0.72f, 0.3f),
						Detail = "主动装备 · " + (flag ? "已持有" : "流派备选")
					});
				}
			}
			return list;
		}

		private void TickNativeMenu()
		{
			if (CommandVisible && open)
			{
				SetOpen(value: false);
				modalReleaseFrame = -1;
			}
			bool flag = open && !CommandVisible;
			if (modalHadDesired && !flag)
			{
				modalReleaseFrame = Time.frameCount + 1;
			}
			modalHadDesired = flag;
			if (OwnsModalInput)
			{
				if (menu == null)
				{
					menu = new NativeMenu(this);
				}
				if (!menuInput.Active)
				{
					menuInput.Acquire(menu.EventSystem);
				}
				menu.Activate(open && !CommandVisible);
				menuInput.Acquire(menu.EventSystem);
				menu.Tick();
			}
			else
			{
				if (menu != null)
				{
					menu.Hide();
				}
				menuInput.Dispose();
			}
		}

		private void InvalidateMenu()
		{
			menu?.Invalidate();
		}

		private void RefreshSafely()
		{
			try
			{
				Refresh();
				analysisErrorLogged = false;
			}
			catch (Exception ex)
			{
				if (!analysisErrorLogged)
				{
					RecordUiIncident("角色分析异常", ex);
					analysisErrorLogged = true;
				}
				plan = null;
				growthPicks.Clear();
				routeOptions.Clear();
				transition = null;
				confirm = false;
				autoArmed = false;
				pending.Clear();
				status = "角色分析暂时失败,已暂停推荐和自动配置;F2仍可关闭或导出诊断。";
				InvalidateMenu();
			}
		}

		private ConfigEntry<int> RouteLock()
		{
			int num = 0;
			if (!oldRouteMigrated.Value)
			{
				if (style.Value > 0 && RouteLogic.Options(bodyId, skills, inventory).Any((RouteOption r) => r.Style == style.Value))
				{
					num = style.Value;
				}
				oldRouteMigrated.Value = true;
			}
			ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("角色流派." + bodyId, "固定方向", num, "0按技能自动;1生存2高频3爆发4固定炮台5近战。仅推荐,不自动发物品。");
			val.Value = Math.Max(0, Math.Min(5, val.Value));
			return val;
		}

		private void SelectRoute(int selected)
		{
			if (plan != null && !string.IsNullOrEmpty(bodyId) && (selected == 0 || routeOptions.Any((RouteOption r) => r.Style == selected)))
			{
				RouteLock().Value = selected;
				style.Value = selected;
				autoArmed = false;
				confirm = false;
				selectedGrowth = "";
				((BaseUnityPlugin)this).Config.Save();
				Refresh();
				InvalidateMenu();
				status = ((selected == 0) ? "已恢复按技能推荐;转型建议仍需手动选择。" : "已记住这个角色的流派,只调整推荐;背包未改变。");
			}
		}

		private string BeginnerSummary()
		{
			if (plan == null)
			{
				return "先在大厅选择角色,进入对局后会按背包更新。";
			}
			GrowthPick growthPick = growthPicks.Where((GrowthPick p) => p.Actionable).ToList().FirstOrDefault();
			return ((growthPick == null) ? "本次没有足够依据的候选" : ((growthPick.Category == "恢复" || growthPick.Category == "防护") ? "先补容错,再追求伤害" : ((growthPick.Category == "机动") ? "先补跑图与躲避能力" : "优先完善当前输出与清怪手段"))) + "。先看本次物品品质,再拿对应推荐;参考数量不是一次要拿满。";
		}

		private void RecordUiIncident(string area, Exception ex)
		{
			recoveries++;
			string text = DateTime.Now.ToString("HH:mm:ss") + " " + area + ":" + ex.GetType().Name + " " + ex.Message;
			uiIncidents.Enqueue(text);
			while (uiIncidents.Count > 12)
			{
				uiIncidents.Dequeue();
			}
			((BaseUnityPlugin)this).Logger.LogWarning((object)text);
		}

		private void ReleaseModal()
		{
			open = false;
			confirm = false;
			modalReleaseFrame = -1;
			modalHadDesired = false;
			try
			{
				menu?.Hide();
			}
			final