Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BeginnerBuilds v0.6.3
plugins/BeginnerBuilds/BeginnerBuilds.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.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