using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GlobalEnums; using GlobalSettings; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using SilksongItemRandomizer; using StartingAbilityPicker; using TeamCherry.Localization; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCompany("SilksongItemRandomizer")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("SilksongItemRandomizer")] [assembly: AssemblyTitle("SilksongItemRandomizer")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/YourGitHubUsername/SilksongItemRandomizer")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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; } } } public class HotkeyHandler : MonoBehaviour { private GUIStyle _tipStyle; private static bool _isChineseCache; private void Update() { if (Input.GetKeyDown((KeyCode)286)) { TestUnlockEvaHeal(); } if (Input.GetKeyDown((KeyCode)287)) { WarpToLastBench(); } if (Input.GetKeyDown((KeyCode)289)) { ToggleRecentItemsUI(); } if (Input.GetKeyDown((KeyCode)290)) { Plugin.Instance?.DumpAllMappings(); } if (Input.GetKeyDown((KeyCode)27)) { Plugin.Instance?.RefreshBenchwarpUI(); } } private void TestUnlockEvaHeal() { //IL_011f: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) PlayerData instance = PlayerData.instance; if (instance == null) { Plugin.Log.LogError((object)"PlayerData 不可用"); return; } Plugin.Log.LogInfo((object)"=== 开始尝试所有方式解锁 EvaHeal(风铃摇)==="); instance.HasSeenEvaHeal = true; Plugin.Log.LogInfo((object)"1. HasSeenEvaHeal = true"); instance.HasBoundCrestUpgrader = true; Plugin.Log.LogInfo((object)"2. HasBoundCrestUpgrader = true"); instance.CrestUpgraderOfferedFinal = true; instance.CrestPreUpgradeTalked = true; instance.CrestTalkedPurpose = true; instance.CrestUpgraderTalkedSnare = true; Plugin.Log.LogInfo((object)"3. 设置纹章升级相关标志: CrestUpgraderOfferedFinal, CrestPreUpgradeTalked, CrestTalkedPurpose, CrestUpgraderTalkedSnare = true"); instance.chapelClosed_reaper = true; instance.chapelClosed_wanderer = true; instance.chapelClosed_beast = true; instance.chapelClosed_witch = true; instance.chapelClosed_toolmaster = true; instance.chapelClosed_shaman = true; Plugin.Log.LogInfo((object)"4. 设置所有 chapelClosed 标志 = true"); instance.completedMemory_reaper = true; instance.completedMemory_wanderer = true; instance.completedMemory_beast = true; instance.completedMemory_witch = true; instance.completedMemory_toolmaster = true; instance.completedMemory_shaman = true; Plugin.Log.LogInfo((object)"5. 设置所有 completedMemory 标志 = true"); string[] array = new string[3] { "EvaHeal", "Sylphsong", "Slythsong" }; foreach (string text in array) { try { Data data = ((SerializableNamedList)(object)instance.Tools).GetData(text); data.IsUnlocked = true; data.AmountLeft = 1; ((SerializableNamedList)(object)instance.Tools).SetData(text, data); Plugin.Log.LogInfo((object)("6. 已解锁工具 " + text)); } catch (Exception ex) { Plugin.Log.LogWarning((object)("6. 工具 " + text + " 不存在或无法修改: " + ex.Message)); } } try { Data data2 = ((SerializableNamedList)(object)instance.Collectables).GetData("EvaHeal"); data2.Amount = 1; ((SerializableNamedList)(object)instance.Collectables).SetData("EvaHeal", data2); Plugin.Log.LogInfo((object)"7. 已设置 Collectables[EvaHeal].Amount = 1"); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("7. 设置 Collectables 失败: " + ex2.Message)); } try { MethodInfo methodInfo = Type.GetType("AutoSaveManager, Assembly-CSharp")?.GetMethod("Save", new Type[1] { typeof(Enum) }); FieldInfo fieldInfo = Type.GetType("AutoSaveName, Assembly-CSharp")?.GetField("GAINED_SLYTHSONG"); if (methodInfo != null && fieldInfo != null) { methodInfo.Invoke(null, new object[1] { fieldInfo.GetValue(null) }); Plugin.Log.LogInfo((object)"8. 已触发 GAINED_SLYTHSONG 自动存档"); } else { Plugin.Log.LogWarning((object)"8. 未找到 AutoSaveManager.Save 方法或 GAINED_SLYTHSONG 枚举"); } } catch (Exception ex3) { Plugin.Log.LogWarning((object)("8. 触发自动存档失败: " + ex3.Message)); } try { Type type = Type.GetType("InventoryCollectableItemSelectionHelper, Assembly-CSharp"); if (type != null) { PropertyInfo property = type.GetProperty("LastSelectionUpdate", BindingFlags.Static | BindingFlags.Public); if (property != null) { Type nestedType = type.GetNestedType("SelectionType"); if (nestedType != null) { object value = Enum.Parse(nestedType, "EvaHeal"); property.SetValue(null, value); Plugin.Log.LogInfo((object)"9. 已触发 InventoryCollectableItemSelectionHelper.SelectionType.EvaHeal"); } } } } catch (Exception ex4) { Plugin.Log.LogWarning((object)("9. 触发物品栏选择失败: " + ex4.Message)); } try { HeroController instance2 = HeroController.instance; if ((Object)(object)instance2 != (Object)null) { instance2.AddSilk(1, true); Plugin.Log.LogInfo((object)"10. 已添加 1 丝线(测试用)"); } } catch (Exception ex5) { Plugin.Log.LogWarning((object)("10. 添加丝线失败: " + ex5.Message)); } Plugin.Log.LogInfo((object)"=== 解锁尝试完成,请坐椅子并观察丝线是否自动恢复 ==="); Plugin.Log.LogInfo((object)"如果仍未恢复,请将日志提交给开发者分析。"); } private void WarpToLastBench() { try { PlayerData instance = PlayerData.instance; if (instance == null) { Plugin.Log.LogError((object)"[HotkeyHandler] PlayerData 不可用"); return; } string respawnScene = instance.respawnScene; if (string.IsNullOrEmpty(respawnScene)) { Plugin.Log.LogWarning((object)"[HotkeyHandler] 重生点场景为空,请先坐一次椅子"); return; } Plugin.Log.LogInfo((object)("[HotkeyHandler] 传送至重生点: " + respawnScene + " / " + instance.respawnMarkerName)); GameManager gm = GameManager.instance; gm.SaveGame((Action)delegate(bool success) { if (!success) { Plugin.Log.LogError((object)"[HotkeyHandler] 保存游戏失败"); } else { gm.LoadGameFromUI(gm.profileID); } }); } catch (Exception ex) { Plugin.Log.LogError((object)("[HotkeyHandler] 传送异常: " + ex.Message)); } } private static void ToggleRecentItemsUI() { RecentItemsUI.Toggle(); Plugin.Log.LogInfo((object)("最近获得物品UI " + (RecentItemsUI.IsVisible ? "显示" : "隐藏"))); } private void OnGUI() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown try { if (IsBenchwarpMenuVisible()) { if (_tipStyle == null) { GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 48, alignment = (TextAnchor)4 }; val.normal.textColor = Color.red; _tipStyle = val; } string text = Locale.Get("按 F6 可直接传送"); float num = ((float)Screen.width - 600f) / 2f; float num2 = (float)Screen.height * 0.66f; GUI.Label(new Rect(num, num2, 600f, 80f), text, _tipStyle); } } catch { } } private static bool IsBenchwarpMenuVisible() { try { Type type = Type.GetType("Benchwarp.Components.GUIController, Benchwarp"); if (type == null) { GameObject val = GameObject.Find("WarpMenu") ?? GameObject.Find("BenchwarpMenu"); return (Object)(object)val != (Object)null && val.activeInHierarchy; } PropertyInfo property = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public); if (property == null) { return false; } object value = property.GetValue(null); if (value != null) { PropertyInfo property2 = type.GetProperty("IsDisplaying"); if (property2 != null && (bool)property2.GetValue(value)) { return true; } } GameObject val2 = GameObject.Find("WarpMenu") ?? GameObject.Find("BenchwarpMenu"); return (Object)(object)val2 != (Object)null && val2.activeInHierarchy; } catch { return false; } } } namespace SilksongItemRandomizer { [HarmonyPatch(typeof(HeroController), "SetBenchRespawn", new Type[] { typeof(RespawnMarker), typeof(string), typeof(int) })] public static class BenchRespawnPatch { public interface IBenchRespawnSaveDataAccessor { string GetLastUnlockedCrest(); } [CompilerGenerated] private sealed class d__7 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string originalCrestId; public HeroController hero; private string 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(7f); <>1__state = 1; return true; case 1: { <>1__state = -1; _activeCoroutine = null; 5__2 = _saveData?.GetLastUnlockedCrest() ?? ""; if (string.IsNullOrEmpty(5__2)) { Plugin.Log.LogInfo((object)"纹章随机总开关关闭或无最后解锁记录,跳过重生替换"); return false; } Plugin.Log.LogInfo((object)("重生强制替换: " + originalCrestId + " -> " + 5__2)); typeof(ToolItemManager).GetMethod("SetEquippedCrest", new Type[1] { typeof(string) })?.Invoke(null, new object[1] { 5__2 }); HeroController obj = hero; if (obj != null) { obj.ResetAllCrestState(); } <>2__current = null; <>1__state = 2; return true; } case 2: <>1__state = -1; ToolItemManager.SendEquippedChangedEvent(true); _lastExecutionTime = Time.time; Plugin.Log.LogInfo((object)("替换完成,当前装备: " + 5__2)); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IBenchRespawnSaveDataAccessor _saveData; private static Coroutine _activeCoroutine; private static float _lastExecutionTime; private const float MinInterval = 10f; public static void Initialize(IBenchRespawnSaveDataAccessor accessor) { _saveData = accessor; } [HarmonyPostfix] private static void Postfix(HeroController __instance) { try { if (!((Object)(object)__instance == (Object)null) && PlayerData.instance != null && _activeCoroutine == null && !(Time.time - _lastExecutionTime < 10f)) { string currentCrestID = PlayerData.instance.CurrentCrestID; if (!string.IsNullOrEmpty(currentCrestID)) { Plugin.Log.LogInfo((object)("重生触发: 延迟7秒处理纹章 " + currentCrestID)); _activeCoroutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedReplace(currentCrestID, __instance)); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"BenchRespawnPatch异常: {arg}"); } } [IteratorStateMachine(typeof(d__7))] private static IEnumerator DelayedReplace(string originalCrestId, HeroController hero) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { originalCrestId = originalCrestId, hero = hero }; } public static void ResetCooldown() { if (_activeCoroutine != null) { _activeCoroutine = null; } _lastExecutionTime = 0f; } } [HarmonyPatch] public static class BenchwarpTranslator { private static readonly Dictionary ChineseMap = new Dictionary(); private static bool DetectChinese() { try { Type type = Type.GetType("FontManager, Assembly-CSharp"); if (type != null) { FieldInfo field = type.GetField("_currentLanguage", BindingFlags.Static | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(null); if (value != null) { string text = value.ToString().ToUpper(); if (text == "ZH" || text == "ZH_TW") { return true; } } } } } catch { } try { GameSettings val = GameManager.instance?.gameSettings; if (val != null) { FieldInfo field2 = ((object)val).GetType().GetField("language", BindingFlags.Instance | BindingFlags.Public); if (field2 != null) { object value2 = field2.GetValue(val); if (value2 != null) { string text2 = value2.ToString().ToUpper(); if (text2 == "ZH" || text2 == "ZH_TW") { return true; } } } } } catch { } return false; } private static MethodBase TargetMethod() { return Type.GetType("Benchwarp.Util.Localization, Benchwarp")?.GetMethod("GetLanguageString", BindingFlags.Static | BindingFlags.Public); } [HarmonyPrefix] private static bool Prefix(string key, ref string __result) { if (DetectChinese() && ChineseMap.TryGetValue(key, out var value)) { __result = value; return false; } return true; } public static void RefreshUI() { GameObject val = GameObject.Find("WarpMenu") ?? GameObject.Find("BenchwarpMenu"); if ((Object)(object)val != (Object)null && val.activeInHierarchy) { val.SetActive(false); val.SetActive(true); Debug.Log((object)"[Benchwarp] UI refreshed."); } } } public interface ICrestSaveDataAccessor { Dictionary GetCrestMappings(); void SaveCrestMappings(Dictionary mappings); HashSet GetUnlockedCrests(); void SaveUnlockedCrests(HashSet unlockedCrests); string GetLastUnlockedCrest(); void SetLastUnlockedCrest(string crestName); } public static class CrestRandomizer { private static bool _initialized = false; private static List _allCrests; private static ICrestSaveDataAccessor _saveData; private static Random _rng; private static int _seed; private static bool _enabled = true; private static bool _temporaryDisable = false; public static readonly HashSet ExcludeFromPool = new HashSet(StringComparer.OrdinalIgnoreCase) { "Hunter", "Hunter_v2", "Hunter_v3", "Witch_v2", "Cursed", "Cloakless" }; public static bool IsEnabled { get { if (_enabled) { return !_temporaryDisable; } return false; } } public static List CrestList => _allCrests; public static IReadOnlyDictionary CrestMappings => new Dictionary(_saveData.GetCrestMappings()); public static IEnumerable UnlockedCrests => _saveData.GetUnlockedCrests().ToList(); public static string LastUnlockedCrest { get { if (!IsEnabled) { return ""; } return _saveData.GetLastUnlockedCrest(); } private set { _saveData.SetLastUnlockedCrest(value); } } public static void Initialize(int seed, bool enabled, ICrestSaveDataAccessor saveDataAccessor) { _seed = seed; _rng = ((seed == 0) ? new Random() : new Random(seed)); _enabled = enabled; _saveData = saveDataAccessor; _allCrests = Resources.FindObjectsOfTypeAll().ToList(); EnsureInitialCrests(); _initialized = true; Plugin.Log.LogInfo((object)$"纹章随机初始化完成,已有 {_saveData.GetCrestMappings().Count} 个映射,已解锁 {_saveData.GetUnlockedCrests().Count} 个纹章"); } public static void SetEnabled(bool enabled) { _enabled = enabled; Plugin.Log.LogInfo((object)("纹章随机开关: " + (_enabled ? "启用" : "禁用"))); } public static void DisableRandom() { _temporaryDisable = true; } public static void EnableRandom() { _temporaryDisable = false; } private static void EnsureInitialCrests() { HashSet unlockedCrests = _saveData.GetUnlockedCrests(); if (unlockedCrests.Count == 0) { unlockedCrests.Add("Hunter"); _saveData.SaveUnlockedCrests(unlockedCrests); LastUnlockedCrest = "Hunter"; } foreach (string crestName in unlockedCrests) { ToolCrest val = ((IEnumerable)_allCrests).FirstOrDefault((Func)((ToolCrest c) => c.name == crestName)); if ((Object)(object)val != (Object)null && !val.IsUnlocked) { UnlockCrestDirectly(val); } } } private static void UnlockCrestDirectly(ToolCrest crest) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Data saveData = crest.SaveData; saveData.IsUnlocked = true; crest.SaveData = saveData; } public static void AddUnlockedCrest(string crestName) { HashSet unlockedCrests = _saveData.GetUnlockedCrests(); if (unlockedCrests.Add(crestName)) { _saveData.SaveUnlockedCrests(unlockedCrests); ToolCrest val = ((IEnumerable)_allCrests).FirstOrDefault((Func)((ToolCrest c) => c.name == crestName)); if ((Object)(object)val != (Object)null && !val.IsUnlocked) { UnlockCrestDirectly(val); } LastUnlockedCrest = crestName; Plugin.Log.LogInfo((object)("记录最后解锁纹章: " + LastUnlockedCrest)); } } public static string GetMappedCrestName(string sourceCrestName) { if (!IsEnabled) { return sourceCrestName; } if (_saveData.GetUnlockedCrests().Contains(sourceCrestName)) { return sourceCrestName; } Dictionary crestMappings = _saveData.GetCrestMappings(); if (crestMappings.TryGetValue(sourceCrestName, out var value)) { return value; } List list = (from c in _allCrests where !ExcludeFromPool.Contains(c.name) && !c.name.Contains("_v") && c.name != sourceCrestName select c.name).ToList(); string text; if (list.Count == 0) { text = sourceCrestName; } else { Random random = new Random(_seed ^ sourceCrestName.GetHashCode()); text = list[random.Next(list.Count)]; } crestMappings[sourceCrestName] = text; _saveData.SaveCrestMappings(crestMappings); Plugin.Log.LogInfo((object)("新映射: " + sourceCrestName + " -> " + text)); return text; } public static string GetMappedCrestNameForRespawn(string sourceCrestName) { return GetMappedCrestName(sourceCrestName); } public static void ResetMappings() { _saveData.GetCrestMappings().Clear(); _saveData.SaveCrestMappings(new Dictionary()); _saveData.GetUnlockedCrests().Clear(); EnsureInitialCrests(); Plugin.Log.LogInfo((object)"纹章映射已重置"); } public static void ResetUnlockedCrests() { _saveData.GetUnlockedCrests().Clear(); EnsureInitialCrests(); Plugin.Log.LogInfo((object)"纹章解锁记录已重置"); } public static string GetSourceCrestByTarget(string targetCrestName) { foreach (KeyValuePair crestMapping in _saveData.GetCrestMappings()) { if (crestMapping.Value == targetCrestName) { return crestMapping.Key; } } return null; } } [HarmonyPatch(typeof(ToolCrest), "Unlock")] public static class CrestRandomizePatch { public interface ICrestPatchSaveDataAccessor { HashSet GetDisabledChapels(); void SaveDisabledChapels(HashSet disabledChapels); } private static ICrestPatchSaveDataAccessor _saveData; private static List _allCrests; private static readonly HashSet ProcessedInstanceIds = new HashSet(); private static readonly string[] DisableKeywords = new string[23] { "shrine", "crest", "church", "chapel", "door", "gate", "altar", "pedestal", "weaver", "bell", "bind", "orb", "rune", "memory", "statue", "pillar", "candle", "bench", "lever", "switch", "transition", "entrance", "exit" }; public static void Initialize(ICrestPatchSaveDataAccessor accessor) { _saveData = accessor; _allCrests = Resources.FindObjectsOfTypeAll().ToList(); } public static void ResetProcessedIds() { ProcessedInstanceIds.Clear(); } public static void ResetPersistentData() { if (_saveData != null) { _saveData.GetDisabledChapels().Clear(); _saveData.SaveDisabledChapels(_saveData.GetDisabledChapels()); } Plugin.Log.LogInfo((object)"已清除教堂禁用持久化数据"); } public static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (CrestRandomizer.IsEnabled) { DisableChurchObjectsInScene(scene); } } private static void DisableChurchObjectsInScene(Scene scene) { if (_saveData == null || !_saveData.GetDisabledChapels().Contains(((Scene)(ref scene)).name)) { return; } Plugin.Log.LogInfo((object)("禁用场景 '" + ((Scene)(ref scene)).name + "' 中的教堂相关物体")); int num = 0; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { Transform[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { string name = ((Object)((Component)val).gameObject).name.ToLower(); if (DisableKeywords.Any((string kw) => name.Contains(kw))) { Collider2D[] components = ((Component)val).GetComponents(); for (int k = 0; k < components.Length; k++) { ((Behaviour)components[k]).enabled = false; } Collider[] components2 = ((Component)val).GetComponents(); for (int k = 0; k < components2.Length; k++) { components2[k].enabled = false; } PlayMakerFSM[] components3 = ((Component)val).GetComponents(); for (int k = 0; k < components3.Length; k++) { ((Behaviour)components3[k]).enabled = false; } Animator[] components4 = ((Component)val).GetComponents(); for (int k = 0; k < components4.Length; k++) { ((Behaviour)components4[k]).enabled = false; } Renderer[] components5 = ((Component)val).GetComponents(); for (int k = 0; k < components5.Length; k++) { components5[k].enabled = false; } num++; Plugin.Log.LogInfo((object)(" 已禁用: " + ((Object)((Component)val).gameObject).name)); } } } Plugin.Log.LogInfo((object)$"共禁用 {num} 个物体"); } [HarmonyPrefix] private static bool Prefix(ToolCrest __instance) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (!CrestRandomizer.IsEnabled) { Plugin.Log.LogInfo((object)("[CrestRandomizePatch] 纹章随机总开关关闭,放行原纹章: " + __instance.name)); return true; } try { int instanceID = ((Object)__instance).GetInstanceID(); if (ProcessedInstanceIds.Contains(instanceID)) { return true; } ProcessedInstanceIds.Add(instanceID); string name = __instance.name; string targetName = CrestRandomizer.GetMappedCrestName(name); if (string.IsNullOrEmpty(targetName) || targetName == name) { Plugin.Log.LogInfo((object)("纹章 " + name + " 映射到自身,放行原解锁")); return true; } if (_allCrests == null || _allCrests.Count == 0) { _allCrests = Resources.FindObjectsOfTypeAll().ToList(); } ToolCrest val = ((IEnumerable)_allCrests).FirstOrDefault((Func)((ToolCrest c) => c.name == targetName)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("无法找到目标纹章 " + targetName + ",放行原解锁")); return true; } CrestRandomizer.AddUnlockedCrest(targetName); CrestRandomizer.DisableRandom(); val.Unlock(); CrestRandomizer.EnableRandom(); Scene activeScene = SceneManager.GetActiveScene(); string name2 = ((Scene)(ref activeScene)).name; if (name2.Contains("Chapel") && _saveData != null && !_saveData.GetDisabledChapels().Contains(name2)) { _saveData.GetDisabledChapels().Add(name2); _saveData.SaveDisabledChapels(_saveData.GetDisabledChapels()); Plugin.Log.LogInfo((object)("标记教堂场景 '" + name2 + "',下次进入时将禁用所有教堂物体")); } Plugin.Log.LogInfo((object)("纹章替换: " + name + " -> " + targetName)); return false; } catch (Exception arg) { Plugin.Log.LogError((object)$"CrestRandomizePatch异常: {arg}"); return true; } } } [HarmonyPatch(typeof(CurrencyObjectBase), "Collect")] public static class CurrencyCollectPatch { public interface ICurrencySaveDataAccessor { int GetTotalCollectCount(); void SetTotalCollectCount(int count); bool GetFirstKeyGiven(); void SetFirstKeyGiven(bool given); bool GetSecondKeyGiven(); void SetSecondKeyGiven(bool given); int GetFirstThreshold(); void SetFirstThreshold(int threshold); int GetSecondThreshold(); void SetSecondThreshold(int threshold); } private static ICurrencySaveDataAccessor _saveData; private const string KeyName = "Simple Key"; public static void Initialize(ICurrencySaveDataAccessor saveDataAccessor) { _saveData = saveDataAccessor; } public static void ResetCounters() { if (_saveData != null) { _saveData.SetTotalCollectCount(0); _saveData.SetFirstKeyGiven(given: false); _saveData.SetSecondKeyGiven(given: false); } Plugin.Log.LogInfo((object)"货币保底计数器已重置"); } public static void ResetKeyState() { ResetCounters(); } [HarmonyPostfix] private static void Postfix(bool __result) { if (__result && _saveData != null) { int num = _saveData.GetTotalCollectCount() + 1; _saveData.SetTotalCollectCount(num); int firstThreshold = _saveData.GetFirstThreshold(); int secondThreshold = _saveData.GetSecondThreshold(); if (!_saveData.GetFirstKeyGiven() && num >= firstThreshold) { GiveKey(); _saveData.SetFirstKeyGiven(given: true); Plugin.Log.LogInfo((object)$"第一次钥匙保底触发,当前货币收集次数: {num}"); } else if (!_saveData.GetSecondKeyGiven() && num >= secondThreshold) { GiveKey(); _saveData.SetSecondKeyGiven(given: true); Plugin.Log.LogInfo((object)$"第二次钥匙保底触发,当前货币收集次数: {num}"); } } } private static void GiveKey() { SavedItem val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((SavedItem i) => ((Object)i).name == "Simple Key")); if ((Object)(object)val != (Object)null) { TryGetPatch.BypassRandom = true; try { val.TryGet(false, true); return; } finally { TryGetPatch.BypassRandom = false; } } Plugin.Log.LogError((object)"钥匙保底失败:找不到物品 Simple Key"); } } public static class EnemyRandoAdjuster { private static bool _patched; private static object _originalEnemyRandoType; private static object _originalBossRandoType; private static object _originalMiscRandoType; private static Type _randoTypeEnum; private static Type _settingsType; private static FieldInfo _enemyRandoTypeField; private static FieldInfo _bossRandoTypeField; private static FieldInfo _miscRandoTypeField; private static Type _replacedEnemyType; private static Type _replacementEnemyType; private static FieldInfo _replacementsField; private static bool _enabled; public static bool Enabled { get { return _enabled; } set { if (_enabled != value) { _enabled = value; SetEnemyRandoConfig(value); if (!value) { RestoreAllReplacedEnemies(); } } } } public static bool ScaleRandomEnabled { get; set; } public static float ScaleMin { get; set; } public static float ScaleMax { get; set; } static EnemyRandoAdjuster() { _patched = false; _enabled = true; ScaleRandomEnabled = true; ScaleMin = 0.5f; ScaleMax = 2f; _settingsType = Type.GetType("EnemyRando.Settings, EnemyRando"); if (_settingsType != null) { _enemyRandoTypeField = _settingsType.GetField("EnemyRandoType", BindingFlags.Static | BindingFlags.Public); _bossRandoTypeField = _settingsType.GetField("BossRandoType", BindingFlags.Static | BindingFlags.Public); _miscRandoTypeField = _settingsType.GetField("MiscRandoType", BindingFlags.Static | BindingFlags.Public); _randoTypeEnum = Type.GetType("EnemyRando.Settings+RandoType, EnemyRando"); } _replacedEnemyType = Type.GetType("EnemyRando.ReplacedEnemy, EnemyRando"); _replacementEnemyType = Type.GetType("EnemyRando.ReplacementEnemy, EnemyRando"); if (_replacedEnemyType != null) { _replacementsField = _replacedEnemyType.GetField("replacements", BindingFlags.Instance | BindingFlags.Public); } } public static void TryPatch(Harmony harmony) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown if (_patched) { return; } Type type = Type.GetType("EnemyRando.Randomiser, EnemyRando"); if (type == null) { Plugin.Log.LogInfo((object)"[EnemyRandoAdjuster] EnemyRando not found, skip patch."); return; } MethodInfo method = type.GetMethod("SpawnRandomEnemy", BindingFlags.Static | BindingFlags.NonPublic); if (method == null) { Plugin.Log.LogWarning((object)"[EnemyRandoAdjuster] SpawnRandomEnemy method not found."); return; } HarmonyMethod val = new HarmonyMethod(typeof(EnemyRandoAdjuster).GetMethod("Prefix", BindingFlags.Static | BindingFlags.NonPublic)); HarmonyMethod val2 = new HarmonyMethod(typeof(EnemyRandoAdjuster).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic)); harmony.Patch((MethodBase)method, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _patched = true; Plugin.Log.LogInfo((object)"[EnemyRandoAdjuster] Patch applied successfully."); SaveOriginalConfig(); } private static void SaveOriginalConfig() { if (_settingsType == null) { return; } try { if (_enemyRandoTypeField != null) { _originalEnemyRandoType = _enemyRandoTypeField.GetValue(null); } if (_bossRandoTypeField != null) { _originalBossRandoType = _bossRandoTypeField.GetValue(null); } if (_miscRandoTypeField != null) { _originalMiscRandoType = _miscRandoTypeField.GetValue(null); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("保存 EnemyRando 原始配置失败: " + ex.Message)); } } private static void SetEnemyRandoConfig(bool enabled) { if (_settingsType == null || _randoTypeEnum == null) { return; } try { object value = Enum.Parse(_randoTypeEnum, "Disabled"); object obj = Enum.Parse(_randoTypeEnum, "Any"); if (enabled) { _enemyRandoTypeField?.SetValue(null, _originalEnemyRandoType ?? obj); _bossRandoTypeField?.SetValue(null, _originalBossRandoType ?? obj); _miscRandoTypeField?.SetValue(null, _originalMiscRandoType ?? obj); } else { _enemyRandoTypeField?.SetValue(null, value); _bossRandoTypeField?.SetValue(null, value); _miscRandoTypeField?.SetValue(null, value); } Plugin.Log.LogInfo((object)("[EnemyRandoAdjuster] 设置随机配置: " + (enabled ? "开启" : "关闭"))); } catch (Exception arg) { Plugin.Log.LogError((object)$"设置 EnemyRando 配置失败: {arg}"); } } private static void RestoreAllReplacedEnemies() { if (_replacedEnemyType == null) { return; } Object[] array = Resources.FindObjectsOfTypeAll(_replacedEnemyType); foreach (Object val in array) { Object obj = ((val is Component) ? val : null); GameObject val2 = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)val2 == (Object)null || !(_replacementsField?.GetValue(val) is IList list) || list.Count == 0) { continue; } HealthManager component = val2.GetComponent(); if ((Object)(object)component == (Object)null) { continue; } val2.SetActive(true); component.isDead = false; foreach (object item in list) { if (item != null) { object obj2 = ((item is Component) ? item : null); Object.Destroy((Object)(object)((obj2 != null) ? ((Component)obj2).gameObject : null)); } } (_replacementsField.GetValue(val) as IList)?.Clear(); Object.Destroy((val is Component) ? val : null); } Plugin.Log.LogInfo((object)"[EnemyRandoAdjuster] 已恢复所有被替换的敌人"); } private static bool Prefix(HealthManager source, int hp) { if (!_enabled) { if (!((Component)source).gameObject.activeSelf) { ((Component)source).gameObject.SetActive(true); } source.hp = hp; if (_replacedEnemyType != null) { Component component = ((Component)source).GetComponent(_replacedEnemyType); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } Plugin.Log.LogInfo((object)$"[EnemyRandoAdjuster] Disabled, restored {((Object)source).name} hp to {hp}"); return false; } return true; } private static void Postfix(bool __result, HealthManager source, int hp) { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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) if (!_enabled || !__result || (Object)(object)source == (Object)null || _replacedEnemyType == null) { return; } Component component = ((Component)source).GetComponent(_replacedEnemyType); if ((Object)(object)component == (Object)null || _replacementsField == null || !(_replacementsField.GetValue(component) is IList list) || list.Count == 0) { return; } foreach (object item in list) { object obj = ((item is Component) ? item : null); HealthManager val = ((obj != null) ? ((Component)obj).GetComponent() : null); if (!((Object)(object)val == (Object)null)) { val.hp = hp; if (ScaleRandomEnabled && Random.value < 0.2f) { float num = 1f - Mathf.Sin(Random.value * (float)Math.PI); float num2 = ScaleMin + (ScaleMax - ScaleMin) * num; ((Component)val).transform.localScale = Vector3.Scale(((Component)val).transform.localScale, new Vector3(num2, num2, num2)); } } } } } [HarmonyPatch] public static class Extracurrencypickup { public interface IExtraPickupSaveDataAccessor { HashSet GetPickedPositions(); void SavePickedPositions(HashSet positions); } [CompilerGenerated] private sealed class d__9 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Vector3 position; public string itemId; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 1; return true; case 1: <>1__state = -1; SpawnPickupAt(position, itemId); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IExtraPickupSaveDataAccessor _saveData; private static bool _isInitialized = false; private static readonly Dictionary> pickupTable = new Dictionary> { ["Tut_01"] = new List<(Vector3, string)> { (new Vector3(26f, 77f, 0f), "Simple Key") }, ["Bonetown"] = new List<(Vector3, string)> { (new Vector3(224f, 80f, 0f), "Simple Key"), (new Vector3(151f, 69f, 0f), "Simple Key") }, ["Bone_01c"] = new List<(Vector3, string)> { (new Vector3(176f, 58f, 0f), "Simple Key"), (new Vector3(139f, 7.5f, 0f), "Simple Key") }, ["Bone_01"] = new List<(Vector3, string)> { (new Vector3(118f, 7.5f, 0f), "Simple Key") }, ["Bone_04"] = new List<(Vector3, string)> { (new Vector3(204f, 5.5f, 0f), "Simple Key") }, ["Mosstown_01"] = new List<(Vector3, string)> { (new Vector3(48f, 23.5f, 0f), "Simple Key") }, ["Mosstown_02"] = new List<(Vector3, string)> { (new Vector3(154f, 55.5f, 0f), "Simple Key") }, ["Bone_14"] = new List<(Vector3, string)> { (new Vector3(129f, 8.5f, 0f), "Simple Key") }, ["Bone_19"] = new List<(Vector3, string)> { (new Vector3(28f, 13.5f, 0f), "Simple Key") }, ["Belltown_basement_03"] = new List<(Vector3, string)> { (new Vector3(65.5f, 5.5f, 0f), "Simple Key"), (new Vector3(71f, 116.5f, 0f), "Simple Key") }, ["Bone_08"] = new List<(Vector3, string)> { (new Vector3(30.5f, 47.5f, 0f), "Simple Key") }, ["Bone_09"] = new List<(Vector3, string)> { (new Vector3(6.5f, 36.5f, 0f), "Simple Key") }, ["Bone_East_03"] = new List<(Vector3, string)> { (new Vector3(153f, 22.5f, 0f), "Simple Key") }, ["Ant_04_left"] = new List<(Vector3, string)> { (new Vector3(7f, 29f, 0f), "Simple Key") }, ["Ant_21"] = new List<(Vector3, string)> { (new Vector3(48.5f, 74f, 0f), "Simple Key") }, ["Dock_06_Church"] = new List<(Vector3, string)> { (new Vector3(11f, 21.5f, 0f), "Simple Key") }, ["Bone_10"] = new List<(Vector3, string)> { (new Vector3(8f, 43.5f, 0f), "Simple Key"), (new Vector3(112.5f, 66.5f, 0f), "Simple Key"), (new Vector3(30f, 45.5f, 0f), "Simple Key") }, ["Bone_11"] = new List<(Vector3, string)> { (new Vector3(8f, 9.5f, 0f), "Simple Key") }, ["Aspid_01"] = new List<(Vector3, string)> { (new Vector3(10.5f, 7.5f, 0f), "Simple Key") }, ["Bonegrave"] = new List<(Vector3, string)> { (new Vector3(270.5f, 72.5f, 0f), "Simple Key") }, ["Chapel_Wanderer"] = new List<(Vector3, string)> { (new Vector3(79.5f, 106.4f, 0f), "Simple Key") }, ["Shellwood_26"] = new List<(Vector3, string)> { (new Vector3(98.5f, 75.5f, 0f), "Simple Key") }, ["Belltown_04"] = new List<(Vector3, string)> { (new Vector3(77f, 48.5f, 0f), "Simple Key"), (new Vector3(63f, 19.5f, 0f), "Simple Key") }, ["Bone_East_17"] = new List<(Vector3, string)> { (new Vector3(7f, 84.5f, 0f), "Simple Key"), (new Vector3(42f, 96.5f, 0f), "Simple Key") }, ["Bone_East_17b"] = new List<(Vector3, string)> { (new Vector3(12f, 31.5f, 0f), "Simple Key") }, ["Bone_East_16"] = new List<(Vector3, string)> { (new Vector3(11f, 16.5f, 0f), "Simple Key") }, ["Bone_East_08"] = new List<(Vector3, string)> { (new Vector3(59f, 21.5f, 0f), "Simple Key") }, ["Bone_East_14"] = new List<(Vector3, string)> { (new Vector3(88f, 40.5f, 0f), "Simple Key") }, ["Bone_East_14b"] = new List<(Vector3, string)> { (new Vector3(250f, 52.5f, 0f), "Simple Key") }, ["Bone_East_07"] = new List<(Vector3, string)> { (new Vector3(10f, 165.5f, 0f), "Simple Key") }, ["Bone_East_09b"] = new List<(Vector3, string)> { (new Vector3(61f, 141.5f, 0f), "Simple Key") }, ["Greymoor_15"] = new List<(Vector3, string)> { (new Vector3(57.3f, 74.5f, 0f), "Simple Key") }, ["Greymoor_15b"] = new List<(Vector3, string)> { (new Vector3(205f, 61.5f, 0f), "Simple Key"), (new Vector3(198f, 41.5f, 0f), "Simple Key") }, ["Greymoor_22"] = new List<(Vector3, string)> { (new Vector3(88f, 25.5f, 0f), "Simple Key") }, ["Greymoor_02"] = new List<(Vector3, string)> { (new Vector3(52f, 90.5f, 0f), "Simple Key") }, ["Greymoor_01"] = new List<(Vector3, string)> { (new Vector3(8.61f, 17.5f, 0f), "Simple Key") }, ["Greymoor_04"] = new List<(Vector3, string)> { (new Vector3(32f, 36.5f, 0f), "Simple Key") }, ["Greymoor_05"] = new List<(Vector3, string)> { (new Vector3(95f, 62.5f, 0f), "Simple Key"), (new Vector3(7f, 19f, 0f), "Simple Key") }, ["Greymoor_06"] = new List<(Vector3, string)> { (new Vector3(6f, 79.5f, 0f), "Simple Key") }, ["Greymoor_07"] = new List<(Vector3, string)> { (new Vector3(28f, 10.5f, 0f), "Simple Key") }, ["Greymoor_08"] = new List<(Vector3, string)> { (new Vector3(140f, 30.5f, 0f), "Simple Key") }, ["Shellwood_11"] = new List<(Vector3, string)> { (new Vector3(59f, 21.5f, 0f), "Simple Key") }, ["Coral_12"] = new List<(Vector3, string)> { (new Vector3(87f, 34.5f, 0f), "Simple Key") }, ["Song_01"] = new List<(Vector3, string)> { (new Vector3(19.5f, 80.5f, 0f), "Simple Key"), (new Vector3(109f, 129.5f, 0f), "Simple Key") }, ["Song_11"] = new List<(Vector3, string)> { (new Vector3(44f, 44.5f, 0f), "Simple Key") }, ["Song_03"] = new List<(Vector3, string)> { (new Vector3(130f, 4.5f, 0f), "Simple Key") }, ["Song_15"] = new List<(Vector3, string)> { (new Vector3(6.5f, 6.5f, 0f), "Simple Key") }, ["Song_17"] = new List<(Vector3, string)> { (new Vector3(34.5f, 100.5f, 0f), "Simple Key") }, ["Hang_08"] = new List<(Vector3, string)> { (new Vector3(19.5f, 195f, 0f), "Simple Key") }, ["Library_04"] = new List<(Vector3, string)> { (new Vector3(51f, 77f, 0f), "Simple Key") }, ["Library_06"] = new List<(Vector3, string)> { (new Vector3(36.5f, 63f, 0f), "Simple Key") }, ["Library_07"] = new List<(Vector3, string)> { (new Vector3(39f, 139.5f, 0f), "Simple Key") }, ["Dock_02"] = new List<(Vector3, string)> { (new Vector3(103f, 51.5f, 0f), "Simple Key") }, ["Bone_East_24"] = new List<(Vector3, string)> { (new Vector3(246f, 65.5f, 0f), "Simple Key") }, ["Bone_East_18"] = new List<(Vector3, string)> { (new Vector3(139f, 36.5f, 0f), "Simple Key") }, ["Bone_East_18b"] = new List<(Vector3, string)> { (new Vector3(133f, 6.5f, 0f), "Simple Key") }, ["Bone_01b"] = new List<(Vector3, string)> { (new Vector3(7f, 85.5f, 0f), "Simple Key") }, ["Bone_East_15"] = new List<(Vector3, string)> { (new Vector3(47f, 8.5f, 0f), "Simple Key") }, ["Song_09"] = new List<(Vector3, string)> { (new Vector3(11f, 56.5f, 0f), "Simple Key") } }; public static void Initialize(IExtraPickupSaveDataAccessor saveDataAccessor) { _saveData = saveDataAccessor; _isInitialized = true; Plugin.Log.LogInfo((object)"[Extracurrencypickup] 初始化完成"); } public static void RegisterAll() { Plugin.Log.LogInfo((object)"[Extracurrencypickup] 已注册 Harmony 补丁(由 API 管理)"); } public static void ResetAll() { if (_saveData != null) { _saveData.GetPickedPositions().Clear(); } Plugin.SaveGlobalData(); Plugin.Log.LogInfo((object)"[Extracurrencypickup] 所有坐标记录已重置"); } private static bool IsPositionPicked(string sceneName, Vector3 pos, float tolerance = 2f) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) if (_saveData == null) { return false; } foreach (string pickedPosition in _saveData.GetPickedPositions()) { if (!pickedPosition.StartsWith(sceneName + "_")) { continue; } string text = pickedPosition.Substring(sceneName.Length + 1); int num = text.IndexOf('_'); if (num >= 0) { string s = text.Substring(0, num); string text2 = text.Substring(num + 1); int num2 = text2.IndexOf('_'); string s2 = ((num2 >= 0) ? text2.Substring(0, num2) : text2); if (float.TryParse(s, out var result) && float.TryParse(s2, out var result2) && Mathf.Abs(pos.x - result) <= tolerance && Mathf.Abs(pos.y - result2) <= tolerance) { Plugin.Log.LogInfo((object)$"[Extracurrencypickup] 坐标 ({pos.x:F2},{pos.y:F2}) 匹配已记录 ({result:F2},{result2:F2}),跳过生成"); return true; } } } return false; } public static void SpawnPickupsForScene(Scene scene) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (!SilksongItemRandomizerAPI.IsEnabled()) { return; } string name = ((Scene)(ref scene)).name; if (!pickupTable.TryGetValue(name, out List<(Vector3, string)> value)) { return; } foreach (var (val, itemId) in value) { if (!IsPositionPicked(name, val) && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedSpawn(val, itemId)); } } } [IteratorStateMachine(typeof(d__9))] private static IEnumerator DelayedSpawn(Vector3 position, string itemId) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__9(0) { position = position, itemId = itemId }; } private static void SpawnPickupAt(Vector3 position, string itemId) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) CollectableItemPickup val = Gameplay.CollectableItemPickupPrefab; if ((Object)(object)val == (Object)null) { CollectableItemPickup val2 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)delegate(CollectableItemPickup p) { //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) Scene scene = ((Component)p).gameObject.scene; return ((Scene)(ref scene)).isLoaded; }); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)"[Extracurrencypickup] No pickup prefab found."); return; } val = val2; } GameObject val3 = Object.Instantiate(((Component)val).gameObject, position, Quaternion.identity); CollectableItemPickup component = val3.GetComponent(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogError((object)"[Extracurrencypickup] Instantiated object has no CollectableItemPickup."); Object.Destroy((Object)(object)val3); return; } SavedItem val4 = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((SavedItem i) => ((Object)i).name == itemId)); if ((Object)(object)val4 == (Object)null) { Plugin.Log.LogError((object)("[Extracurrencypickup] Item '" + itemId + "' not found.")); Object.Destroy((Object)(object)val3); return; } component.SetItem(val4, false); PersistentBoolItem component2 = ((Component)component).GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } val3.SetActive(true); Plugin.Log.LogInfo((object)$"[Extracurrencypickup] Spawned pickup at {position}, item {itemId}"); } [HarmonyPatch(typeof(SavedItem), "TryGet")] [HarmonyPostfix] public static void OnItemTryGet(SavedItem __instance, bool __result) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!__result || _saveData == null) { return; } HeroController instance = HeroController.instance; if (!((Object)(object)instance == (Object)null)) { Scene activeScene = SceneManager.GetActiveScene(); Vector3 position = ((Component)instance).transform.position; string text = $"{((Scene)(ref activeScene)).name}_{position.x:F2}_{position.y:F2}_{position.z:F2}"; if (_saveData.GetPickedPositions().Add(text)) { _saveData.SavePickedPositions(_saveData.GetPickedPositions()); Plugin.Log.LogInfo((object)("[Extracurrencypickup] 记录物品获得坐标: " + text)); } } } } [Serializable] public class GlobalSaveData { public int Version = 2; public Dictionary CrestMappings = new Dictionary(); public HashSet UnlockedCrests = new HashSet(); public string LastUnlockedCrest = ""; public HashSet DisabledChapels = new HashSet(); public HashSet PickedPositions = new HashSet(); public HashSet PickedPickupKeys = new HashSet(); public int CurrencyTotalCollectCount; public bool CurrencyFirstKeyGiven; public bool CurrencySecondKeyGiven; public int CurrencyFirstThreshold = 30; public int CurrencySecondThreshold = 1000; public Dictionary ShopSlotCounts = new Dictionary(); public Dictionary ItemGivenCounts = new Dictionary(); public Dictionary TotalMappings = new Dictionary(); public float VirtualUnlimitedProbability = 0.1f; public float CrestUnlockerProbability = 0.1f; public float NormalLimitedProbability = 0.8f; public int MaxGivenPerItem = 2; public HashSet DestroyedPickupKeys = new HashSet(); public int SilkSpearTryGetCount; public bool SilkSpearGiven; public int SilkSpearPityCount = 10; public bool TrapEnabled; public string TrapDifficulty = "Beginner"; public bool TrapMovementEnabled = true; public HashSet TrapFrostBannedScenes = new HashSet(); public Dictionary> CrestEffects = new Dictionary>(); public HashSet ShopAssignedItemIds = new HashSet(); } [Serializable] public class CurrencyState { public int TotalCollectCount; public bool FirstKeyGiven; public bool SecondKeyGiven; } [HarmonyPatch(typeof(HeroController))] public static class HeroRespawnReset { [CompilerGenerated] private sealed class d__3 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float duration; public HeroController hero; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(duration); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)hero != (Object)null) { hero.cState.invulnerable = false; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float ProtectionDuration = 4f; private static float _protectionEndTime; [HarmonyPatch("FinishedEnteringScene", new Type[] { typeof(bool), typeof(bool) })] [HarmonyPostfix] private static void FinishedEnteringScenePostfix(HeroController __instance) { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) __instance.controlReqlinquished = false; __instance.cState.recoiling = false; __instance.cState.recoilingLeft = false; __instance.cState.recoilingRight = false; __instance.cState.floating = false; typeof(HeroController).GetField("acceptingInput", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(__instance, true); object obj = typeof(HeroController).GetField("inputHandler", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); if (obj != null) { object obj2 = obj.GetType().GetProperty("inputActions")?.GetValue(obj); (obj2?.GetType().GetMethod("ClearInputState"))?.Invoke(obj2, null); } __instance.damageMode = (DamageMode)0; __instance.AffectedByGravity(true); _protectionEndTime = Time.time + 4f; __instance.cState.invulnerable = true; ((MonoBehaviour)__instance).StartCoroutine(ClearInvincibleAfterDelay(__instance, 4f)); } [IteratorStateMachine(typeof(d__3))] private static IEnumerator ClearInvincibleAfterDelay(HeroController hero, float duration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__3(0) { hero = hero, duration = duration }; } [HarmonyPatch("TakeDamage", new Type[] { typeof(GameObject), typeof(CollisionSide), typeof(int), typeof(HazardType), typeof(DamagePropertyFlags) })] [HarmonyPrefix] private static bool TakeDamagePrefix(HeroController __instance) { return Time.time >= _protectionEndTime; } } public static class ItemLimitConfig { public static int LimitSkillItem { get; set; } = 2; public static int LimitRelic { get; set; } = 2; public static int LimitOtherItem { get; set; } = 2; public static int LimitUpSlash { get; set; } = 1; public static int LimitLeftSlash { get; set; } = 1; public static int LimitRightSlash { get; set; } = 1; public static int LimitDashLeft { get; set; } = 1; public static int LimitDashRight { get; set; } = 1; public static int LimitHarpoonLeft { get; set; } = 1; public static int LimitHarpoonRight { get; set; } = 1; public static int LimitFloatLeft { get; set; } = 1; public static int LimitFloatRight { get; set; } = 1; public static int LimitWallJumpLeft { get; set; } = 1; public static int LimitWallJumpRight { get; set; } = 1; public static int LimitHeal { get; set; } = 1; public static int LimitNeedleThrow { get; set; } = 1; public static int LimitThreadSphere { get; set; } = 1; public static int LimitHarpoonDash { get; set; } = 1; public static int LimitSilkCharge { get; set; } = 1; public static int LimitSilkBomb { get; set; } = 1; public static int LimitSilkBossNeedle { get; set; } = 1; public static int LimitNeedolin { get; set; } = 1; public static int LimitParry { get; set; } = 1; public static int LimitNeedolinMemory { get; set; } = 1; public static int LimitFastTravel { get; set; } = 1; public static int LimitEvaHeal { get; set; } = 1; public static int LimitDash { get; set; } = 1; public static int LimitBrolly { get; set; } = 1; public static int LimitDoubleJump { get; set; } = 1; public static int LimitSuperJump { get; set; } = 1; public static int LimitWallJump { get; set; } = 1; public static int LimitChargeSlash { get; set; } = 1; public static int LimitHeartPiece { get; set; } = 2; public static int LimitSpoolPart { get; set; } = 2; public static int LimitMaxSilkRegenUp { get; set; } = 2; public static int LimitUnlockCrestSlot { get; set; } = 2; public static bool EnableInfSilk { get; private set; } = true; public static bool EnableInfFullRestore { get; private set; } = true; public static bool EnableInfBlueHealth { get; private set; } = true; public static bool EnableInfGeo300 { get; private set; } = true; public static bool EnableInfShards300 { get; private set; } = true; public static bool EnableInfSilkParts { get; private set; } = true; public static void Init(ConfigFile config) { Func func = (string section, string key, int defaultValue) => config.Bind(section, key, defaultValue, (ConfigDescription)null).Value; Func obj = (string section, string key, bool defaultValue) => config.Bind(section, key, defaultValue, (ConfigDescription)null).Value; LimitSkillItem = func("Limits", "SkillItem", 2); LimitRelic = func("Limits", "Relic", 2); LimitOtherItem = func("Limits", "OtherItem", 2); LimitUpSlash = func("Limits", "UpSlash", 1); LimitLeftSlash = func("Limits", "LeftSlash", 1); LimitRightSlash = func("Limits", "RightSlash", 1); LimitDashLeft = func("Limits", "DashLeft", 1); LimitDashRight = func("Limits", "DashRight", 1); LimitHarpoonLeft = func("Limits", "HarpoonLeft", 1); LimitHarpoonRight = func("Limits", "HarpoonRight", 1); LimitFloatLeft = func("Limits", "FloatLeft", 1); LimitFloatRight = func("Limits", "FloatRight", 1); LimitWallJumpLeft = func("Limits", "WallJumpLeft", 1); LimitWallJumpRight = func("Limits", "WallJumpRight", 1); LimitHeal = func("Limits", "Heal", 1); LimitNeedleThrow = func("Limits", "NeedleThrow", 1); LimitThreadSphere = func("Limits", "ThreadSphere", 1); LimitHarpoonDash = func("Limits", "HarpoonDash", 1); LimitSilkCharge = func("Limits", "SilkCharge", 1); LimitSilkBomb = func("Limits", "SilkBomb", 1); LimitSilkBossNeedle = func("Limits", "SilkBossNeedle", 1); LimitNeedolin = func("Limits", "Needolin", 1); LimitParry = func("Limits", "Parry", 1); LimitNeedolinMemory = func("Limits", "NeedolinMemory", 1); LimitFastTravel = func("Limits", "FastTravel", 1); LimitEvaHeal = func("Limits", "EvaHeal", 1); LimitDash = func("Limits", "Dash", 1); LimitBrolly = func("Limits", "Brolly", 1); LimitDoubleJump = func("Limits", "DoubleJump", 1); LimitSuperJump = func("Limits", "SuperJump", 1); LimitWallJump = func("Limits", "WallJump", 1); LimitChargeSlash = func("Limits", "ChargeSlash", 1); LimitHeartPiece = func("Limits", "HeartPiece", 2); LimitSpoolPart = func("Limits", "SpoolPart", 2); LimitMaxSilkRegenUp = func("Limits", "MaxSilkRegenUp", 2); LimitUnlockCrestSlot = func("Limits", "UnlockCrestSlot", 2); EnableInfSilk = obj("Limits", "EnableInfSilk", arg3: true); EnableInfFullRestore = obj("Limits", "EnableInfFullRestore", arg3: true); EnableInfBlueHealth = obj("Limits", "EnableInfBlueHealth", arg3: true); EnableInfGeo300 = obj("Limits", "EnableInfGeo300", arg3: true); EnableInfShards300 = obj("Limits", "EnableInfShards300", arg3: true); EnableInfSilkParts = obj("Limits", "EnableInfSilkParts", arg3: true); } public static void Apply(ItemLimitSettings settings) { if (settings != null) { LimitSkillItem = settings.SkillItem; LimitRelic = settings.Relic; LimitOtherItem = settings.OtherItem; LimitUpSlash = settings.UpSlash; LimitLeftSlash = settings.LeftSlash; LimitRightSlash = settings.RightSlash; LimitDashLeft = settings.DashLeft; LimitDashRight = settings.DashRight; LimitHarpoonLeft = settings.HarpoonLeft; LimitHarpoonRight = settings.HarpoonRight; LimitFloatLeft = settings.FloatLeft; LimitFloatRight = settings.FloatRight; LimitWallJumpLeft = settings.WallJumpLeft; LimitWallJumpRight = settings.WallJumpRight; LimitHeal = settings.Heal; LimitNeedleThrow = settings.NeedleThrow; LimitThreadSphere = settings.ThreadSphere; LimitHarpoonDash = settings.HarpoonDash; LimitSilkCharge = settings.SilkCharge; LimitSilkBomb = settings.SilkBomb; LimitSilkBossNeedle = settings.SilkBossNeedle; LimitNeedolin = settings.Needolin; LimitParry = settings.Parry; LimitNeedolinMemory = settings.NeedolinMemory; LimitFastTravel = settings.FastTravel; LimitEvaHeal = settings.EvaHeal; LimitDash = settings.Dash; LimitBrolly = settings.Brolly; LimitDoubleJump = settings.DoubleJump; LimitSuperJump = settings.SuperJump; LimitWallJump = settings.WallJump; LimitChargeSlash = settings.ChargeSlash; LimitHeartPiece = settings.HeartPiece; LimitSpoolPart = settings.SpoolPart; LimitMaxSilkRegenUp = settings.MaxSilkRegenUp; LimitUnlockCrestSlot = settings.UnlockCrestSlot; } } public static void ApplyInfinitePoolSettings(InfinitePoolSettings settings) { if (settings != null) { EnableInfSilk = settings.Silk; EnableInfFullRestore = settings.FullRestore; EnableInfBlueHealth = settings.BlueHealth; EnableInfGeo300 = settings.Geo300; EnableInfShards300 = settings.Shards300; EnableInfSilkParts = settings.SilkParts; } } public static int GetAbilityLimit(string abilityId) { return abilityId switch { "hasNeedleThrow" => LimitNeedleThrow, "hasThreadSphere" => LimitThreadSphere, "hasHarpoonDash" => LimitHarpoonDash, "hasSilkCharge" => LimitSilkCharge, "hasSilkBomb" => LimitSilkBomb, "hasSilkBossNeedle" => LimitSilkBossNeedle, "hasNeedolin" => LimitNeedolin, "hasParry" => LimitParry, "hasNeedolinMemoryPowerup" => LimitNeedolinMemory, "hasFastTravelTeleport" => LimitFastTravel, "HasSeenEvaHeal" => LimitEvaHeal, "hasDash" => LimitDash, "hasBrolly" => LimitBrolly, "hasDoubleJump" => LimitDoubleJump, "hasSuperJump" => LimitSuperJump, "hasWalljump" => LimitWallJump, "hasChargeSlash" => LimitChargeSlash, _ => 1, }; } public static int GetDirectionLimit(string id) { return id switch { "perm:upward" => LimitUpSlash, "perm:left" => LimitLeftSlash, "perm:right" => LimitRightSlash, "perm:hasDash_L" => LimitDashLeft, "perm:hasDash_R" => LimitDashRight, "perm:hasHarpoonDash_L" => LimitHarpoonLeft, "perm:hasHarpoonDash_R" => LimitHarpoonRight, "perm:hasBrolly_L" => LimitFloatLeft, "perm:hasBrolly_R" => LimitFloatRight, "perm:hasWalljump_L" => LimitWallJumpLeft, "perm:hasWalljump_R" => LimitWallJumpRight, "perm:heal" => LimitHeal, _ => 1, }; } public static int GetPreciousLimit(string id) { return id switch { "virt:HeartPiece" => LimitHeartPiece, "virt:SpoolPart" => LimitSpoolPart, "virt:MaxSilkRegenUp" => LimitMaxSilkRegenUp, "virt:UnlockCrestSlot" => LimitUnlockCrestSlot, _ => 2, }; } public static int GetItemTypeLimit(SavedItem item) { if ((Object)(object)item == (Object)null) { return 2; } Type type = ((object)item).GetType(); if (type == typeof(ToolItemSkill) || type.IsSubclassOf(typeof(ToolItemSkill)) || item is ToolItemSkill) { return LimitSkillItem; } if (typeof(CollectableRelic).IsAssignableFrom(type)) { return LimitRelic; } return LimitOtherItem; } } public static class ItemLocalizationRegistrar { public const string CustomSheetName = "SilksongItemRandomizer"; private static readonly HashSet _registeredKeys = new HashSet(); private static Dictionary> _localizationDict; private static bool EnsureLocalizationDict() { if (_localizationDict != null) { return true; } FieldInfo field = typeof(Language).GetField("_currentEntrySheets", BindingFlags.Static | BindingFlags.NonPublic); if (field == null) { Plugin.Log.LogError((object)"[ItemLocalization] 无法获取 Language._currentEntrySheets 字段"); return false; } _localizationDict = field.GetValue(null) as Dictionary>; if (_localizationDict == null) { Plugin.Log.LogError((object)"[ItemLocalization] Language._currentEntrySheets 字段不是预期类型"); return false; } return true; } public static bool RegisterItemName(string key, string displayName) { if (!EnsureLocalizationDict()) { return false; } if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(displayName)) { return false; } if (_registeredKeys.Contains(key)) { return true; } if (!_localizationDict.TryGetValue("SilksongItemRandomizer", out var value)) { value = new Dictionary(); _localizationDict["SilksongItemRandomizer"] = value; } value[key] = displayName; _registeredKeys.Add(key); Plugin.Log.LogDebug((object)("[ItemLocalization] 注册物品名称: " + key + " -> " + displayName)); return true; } public static string GetLocalizationKey(string itemInternalName) { return "item_" + itemInternalName; } public static LocalisedString GetLocalisedString(string itemInternalName) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return new LocalisedString("SilksongItemRandomizer", GetLocalizationKey(itemInternalName)); } public static void RegisterAllKnownItems() { if (!EnsureLocalizationDict()) { return; } SavedItem[] array = Resources.FindObjectsOfTypeAll(); int num = 0; SavedItem[] array2 = array; foreach (SavedItem val in array2) { if (!((Object)(object)val == (Object)null)) { string name = ((Object)val).name; string itemDisplayNameSafe = GetItemDisplayNameSafe(val); if (!string.IsNullOrEmpty(itemDisplayNameSafe) && RegisterItemName(GetLocalizationKey(name), itemDisplayNameSafe)) { num++; } } } Plugin.Log.LogInfo((object)$"[ItemLocalization] 已注册 {num} 个物品的本地化名称"); } private static string GetItemDisplayNameSafe(SavedItem item) { if (typeof(SavedItem).GetMethod("GetPopupName", BindingFlags.Instance | BindingFlags.Public) != null) { MethodInfo method = ((object)item).GetType().GetMethod("GetPopupName", BindingFlags.Instance | BindingFlags.Public); if (method != null && method.DeclaringType == typeof(SavedItem)) { return ((Object)item).name; } } try { return item.GetPopupName(); } catch { return ((Object)item).name; } } public static void Reset() { if (EnsureLocalizationDict()) { if (_localizationDict.ContainsKey("SilksongItemRandomizer")) { _localizationDict["SilksongItemRandomizer"].Clear(); } _registeredKeys.Clear(); Plugin.Log.LogInfo((object)"[ItemLocalization] 已清空所有自定义本地化条目"); } } } public interface ISaveDataAccessor { Dictionary GetItemGivenCounts(); Dictionary GetTotalMappings(); void SaveItemGivenCounts(Dictionary counts); void SaveTotalMappings(Dictionary mappings); } public static class ItemRandomizer { [CompilerGenerated] private sealed class d__23 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int times; public float interval; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__23(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_005c; } <>1__state = -1; 5__2 = 0; goto IL_006c; IL_005c: 5__2++; goto IL_006c; IL_006c: if (5__2 < times) { EventRegister.SendEvent(EventRegisterEvents.AddBlueHealth, (GameObject)null); if (5__2 < times - 1) { <>2__current = (object)new WaitForSeconds(interval); <>1__state = 1; return true; } goto IL_005c; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__26 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string skillField; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__26(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_003b; case 1: <>1__state = -1; goto IL_003b; case 2: { <>1__state = -1; StartingAbilityPickerAPI.GiveSkill(skillField); return false; } IL_003b: if (IsSystemMenuOpen()) { <>2__current = null; <>1__state = 1; return true; } <>2__current = null; <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static List _unlimitedRewards = new List(); private static List _limitedRewards = new List(); private static IRandomReward _cachedCrestUnlocker; private static Random _globalRng; private static int _seed; private static ISaveDataAccessor _saveData; private static float _virtualUnlimitedProbability = 0.1f; private static float _crestUnlockerProbability = 0.1f; private static float _normalLimitedProbability = 0.8f; private static bool _fullRandomModeActive = false; public static readonly HashSet ExcludedNames = new HashSet { "Steel Spines", "Common Spine", "Plasmium", "Sliver Bell", "Seared Organ", "Shredded Organ", "Skewered Organ", "Ragpelt", "Invalid Item Template" }; public static Random Rng => _globalRng; public static bool IsInitialized { get; private set; } = false; public static ToolItemType? LastUnlockedSlotType { get; private set; } public static void Initialize(int seed, ItemRandomizerConfig config, ISaveDataAccessor saveDataAccessor, bool fullRandomMode) { _seed = seed; _globalRng = ((seed == 0) ? new Random() : new Random(seed)); _saveData = saveDataAccessor; _fullRandomModeActive = fullRandomMode; if (config != null) { _virtualUnlimitedProbability = config.VirtualUnlimitedProbability; _crestUnlockerProbability = config.CrestUnlockerProbability; _normalLimitedProbability = config.NormalLimitedProbability; } BuildRewardPools(config, fullRandomMode); IsInitialized = true; } public static void RefreshPool() { if (IsInitialized) { BuildRewardPools(null, _fullRandomModeActive); } } private static void BuildRewardPools(ItemRandomizerConfig config, bool fullRandomMode) { _limitedRewards.Clear(); _unlimitedRewards.Clear(); SavedItem[] array = Resources.FindObjectsOfTypeAll(); List list = new List(); SavedItem[] array2 = array; foreach (SavedItem val in array2) { if (!((Object)(object)val == (Object)null) && !ExcludedNames.Contains(((Object)val).name)) { Type type = ((object)val).GetType(); if (!(val is EnemyJournalRecord) && !type.Name.StartsWith("QuestTarget") && !(type == typeof(Quest)) && !(type == typeof(MainQuest)) && !(type == typeof(SubQuest)) && !(type == typeof(QuestRumour)) && !(type == typeof(FullQuestBase)) && !(type == typeof(BasicQuestBase)) && !(type == typeof(QuestGroup)) && !(type == typeof(QuestGroupBase)) && IsValidItem(val)) { list.Add(val); } } } HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase) { "Swift Step", "Harpoon Dash", "Drifter's Cloak", "Cling Grip", "EvaHeal" }; foreach (SavedItem item in list) { if (!fullRandomMode || !hashSet.Contains(((Object)item).name)) { _limitedRewards.Add(new SavedItemReward(item)); } } BuildAbilityVirtualRewards(fullRandomMode); if (fullRandomMode) { AddDirectionPermissionRewards(); } BuildUnlimitedVirtualRewards(); BuildPreciousVirtualRewards(); _cachedCrestUnlocker = _limitedRewards.FirstOrDefault((IRandomReward r) => r.Id == "virt:UnlockCrestSlot"); Plugin.Log.LogInfo((object)$"随机奖励池构建完成:无限类 {_unlimitedRewards.Count} 个,有限类 {_limitedRewards.Count} 个"); } private static void BuildAbilityVirtualRewards(bool fullRandomMode) { string[] array = new string[17] { "hasNeedleThrow", "hasThreadSphere", "hasSilkCharge", "hasSilkBomb", "hasSilkBossNeedle", "hasParry", "hasHarpoonDash", "hasNeedolin", "hasDash", "hasBrolly", "hasDoubleJump", "hasChargeSlash", "hasSuperJump", "hasWalljump", "HasSeenEvaHeal", "hasNeedolinMemoryPowerup", "hasFastTravelTeleport" }; foreach (string field in array) { if (!fullRandomMode || !IsDirectionSkillField(field)) { var (text, val) = GetAbilityInfo(field); if ((Object)(object)val == (Object)null) { val = GetFallbackIcon(); } if (string.IsNullOrEmpty(text)) { text = field; } VirtualReward item = new VirtualReward(field, text, val, delegate { GiveSkillWithMenuCheck(field); }, () => GetGivenCount(field) >= ItemLimitConfig.GetAbilityLimit(field)); _limitedRewards.Add(item); } } } private static void AddDirectionPermissionRewards() { _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("冲刺左"), "hasDash", allowRight: false, allowLeft: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("冲刺右"), "hasDash", allowRight: true, allowLeft: false)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("飞针左"), "hasHarpoonDash", allowRight: false, allowLeft: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("飞针右"), "hasHarpoonDash", allowRight: true, allowLeft: false)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("漂浮左"), "hasBrolly", allowRight: false, allowLeft: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("漂浮右"), "hasBrolly", allowRight: true, allowLeft: false)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("壁跳左"), "hasWalljump", allowRight: false, allowLeft: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("壁跳右"), "hasWalljump", allowRight: true, allowLeft: false)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("上劈权限"), "upward", allowRight: true, allowLeft: false, isAttack: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("左劈权限"), "left", allowRight: true, allowLeft: false, isAttack: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("右劈权限"), "right", allowRight: true, allowLeft: false, isAttack: true)); _limitedRewards.Add(new DirectionPermissionReward(Locale.Get("回血权限"), "heal", allowRight: true, allowLeft: false, isAttack: false, isHeal: true)); } private static void BuildUnlimitedVirtualRewards() { if (ItemLimitConfig.EnableInfSilk) { _unlimitedRewards.Add(new VirtualReward("virt:Silk_9", Locale.Get("灵丝"), null, delegate { HeroController instance7 = HeroController.instance; if ((Object)(object)instance7 != (Object)null) { for (int k = 0; k < 9; k++) { instance7.AddSilk(1, false); } } }, () => false)); } if (ItemLimitConfig.EnableInfFullRestore) { _unlimitedRewards.Add(new VirtualReward("virt:FullRestore", Locale.Get("完全恢复"), null, delegate { HeroController instance5 = HeroController.instance; PlayerData instance6 = PlayerData.instance; if (!((Object)(object)instance5 == (Object)null) && instance6 != null) { int num = instance6.CurrentMaxHealth - instance6.health; for (int i = 0; i < num; i++) { instance5.AddHealth(1); } int num2 = instance6.CurrentSilkMax - instance6.silk; for (int j = 0; j < num2; j++) { instance5.AddSilk(1, false); } } }, () => false)); } if (ItemLimitConfig.EnableInfBlueHealth) { _unlimitedRewards.Add(new VirtualReward("virt:BlueHealth_5", Locale.Get("蓝血"), null, delegate { Plugin instance4 = Plugin.Instance; if (instance4 != null) { ((MonoBehaviour)instance4).StartCoroutine(AddBlueHealthCoroutine(5, 1f)); } }, () => false)); } if (ItemLimitConfig.EnableInfGeo300) { _unlimitedRewards.Add(new VirtualReward("virt:Geo_300", Locale.Get("念珠"), null, delegate { HeroController instance3 = HeroController.instance; if (instance3 != null) { instance3.AddGeo(300); } }, () => false)); } if (ItemLimitConfig.EnableInfShards300) { _unlimitedRewards.Add(new VirtualReward("virt:Shards_300", Locale.Get("甲壳"), null, delegate { HeroController instance2 = HeroController.instance; if (instance2 != null) { instance2.AddShards(300); } }, () => false)); } if (!ItemLimitConfig.EnableInfSilkParts) { return; } _unlimitedRewards.Add(new VirtualReward("virt:SilkParts_3", Locale.Get("大灵丝碎片"), null, delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddSilkParts(3); } }, () => false)); } private static void BuildPreciousVirtualRewards() { _limitedRewards.Add(new VirtualReward("virt:HeartPiece", Locale.Get("面具碎片"), null, delegate { PlayerData instance4 = PlayerData.instance; if (instance4 != null) { instance4.heartPieces++; } EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); }, () => GetGivenCount("virt:HeartPiece") >= ItemLimitConfig.GetPreciousLimit("virt:HeartPiece"))); _limitedRewards.Add(new VirtualReward("virt:SpoolPart", Locale.Get("丝轴碎片"), null, delegate { PlayerData instance2 = PlayerData.instance; if (instance2 != null) { instance2.silkSpoolParts++; } GameCameras instance3 = GameCameras.instance; if (instance3 != null) { SilkSpool silkSpool = instance3.silkSpool; if (silkSpool != null) { silkSpool.RefreshSilk(); } } EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); }, () => GetGivenCount("virt:SpoolPart") >= ItemLimitConfig.GetPreciousLimit("virt:SpoolPart"))); _limitedRewards.Add(new VirtualReward("virt:MaxSilkRegenUp", Locale.Get("丝线恢复上限 +1"), null, delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddToMaxSilkRegen(1); } }, () => GetGivenCount("virt:MaxSilkRegenUp") >= ItemLimitConfig.GetPreciousLimit("virt:MaxSilkRegenUp"))); _limitedRewards.Add(new VirtualReward("virt:UnlockCrestSlot", Locale.Get("纹章槽位解锁器"), null, delegate { TryUnlockCrestSlot(); }, () => GetGivenCount("virt:UnlockCrestSlot") >= ItemLimitConfig.GetPreciousLimit("virt:UnlockCrestSlot"))); } [IteratorStateMachine(typeof(d__23))] private static IEnumerator AddBlueHealthCoroutine(int times, float interval) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__23(0) { times = times, interval = interval }; } private static bool IsDirectionSkillField(string field) { switch (field) { default: return field == "HasSeenEvaHeal"; case "hasDash": case "hasHarpoonDash": case "hasBrolly": case "hasWalljump": return true; } } private static bool IsSystemMenuOpen() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 try { if ((Object)(object)UIManager.instance != (Object)null && (int)UIManager.instance.uiState == 5) { return true; } GameObject obj = GameObject.Find("PauseMenu"); if (obj != null && obj.activeInHierarchy) { return true; } } catch { } return false; } [IteratorStateMachine(typeof(d__26))] private static IEnumerator WaitForSystemMenuThenGive(string skillField) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__26(0) { skillField = skillField }; } private static void GiveSkillWithMenuCheck(string skillField) { EnsureSpellSlotsUnlocked(); if (IsSystemMenuOpen()) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(WaitForSystemMenuThenGive(skillField)); } else { StartingAbilityPickerAPI.GiveSkill(skillField); } } private static void EnsureSpellSlotsUnlocked() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0121: 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_0130: 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) try { PlayerData instance = PlayerData.instance; if (instance == null) { return; } string crestId = instance.CurrentCrestID; if (string.IsNullOrEmpty(crestId)) { crestId = "Hunter"; } ToolCrest val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((ToolCrest c) => c.name == crestId)); if ((Object)(object)val == (Object)null) { return; } Data saveData = val.SaveData; if (saveData.Slots == null || saveData.Slots.Count == 0) { saveData.Slots = new List(); for (int i = 0; i < val.Slots.Length; i++) { saveData.Slots.Add(new SlotData { IsUnlocked = !val.Slots[i].IsLocked }); } val.SaveData = saveData; } bool flag = false; for (int j = 0; j < val.Slots.Length && j < saveData.Slots.Count; j++) { if (((object)(ToolItemType)(ref val.Slots[j].Type)).ToString().Contains("Spell") && !saveData.Slots[j].IsUnlocked) { SlotData value = saveData.Slots[j]; value.IsUnlocked = true; saveData.Slots[j] = value; flag = true; } } if (flag) { val.SaveData = saveData; Plugin.Log.LogInfo((object)("[ItemRandomizer] 已为纹章 " + crestId + " 解锁法术槽")); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ItemRandomizer] 解锁法术槽失败: " + ex.Message)); } } private static (string displayName, Sprite icon) GetAbilityInfo(string abilityField) { try { string displayName = StartingAbilityPickerAPI.GetDisplayName(abilityField); Sprite icon = StartingAbilityPickerAPI.GetIcon(abilityField); if (!string.IsNullOrEmpty(displayName) && (Object)(object)icon != (Object)null) { return (displayName, icon); } } catch { } object item = abilityField switch { "hasDash" => Locale.Get("疾风步"), "hasBrolly" => Locale.Get("流浪者披风"), "hasDoubleJump" => Locale.Get("雪绒披风"), "hasSuperJump" => Locale.Get("灵丝升腾"), "hasWalljump" => Locale.Get("蛛攀术"), "HasSeenEvaHeal" => Locale.Get("风铃摇"), _ => abilityField, }; Sprite fallbackIcon = GetFallbackIcon(); return ((string)item, fallbackIcon); } private static Sprite GetFallbackIcon() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, Color.white); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), Vector2.zero); } private static Dictionary GetGivenCountsDict() { return _saveData?.GetItemGivenCounts() ?? new Dictionary(); } private static Dictionary GetTotalMappingsDict() { return _saveData?.GetTotalMappings() ?? new Dictionary(); } private static void SaveGivenCounts() { _saveData?.SaveItemGivenCounts(GetGivenCountsDict()); } private static void SaveTotalMappings() { _saveData?.SaveTotalMappings(GetTotalMappingsDict()); } public static int GetGivenCount(string id) { if (!GetGivenCountsDict().TryGetValue(id, out var value)) { return 0; } return value; } public static void AddGivenCount(string id) { Dictionary givenCountsDict = GetGivenCountsDict(); if (givenCountsDict.ContainsKey(id)) { givenCountsDict[id]++; } else { givenCountsDict[id] = 1; } SaveGivenCounts(); } public static void RecordMapping(string sourceKey, string targetKey) { Dictionary totalMappingsDict = GetTotalMappingsDict(); if (!totalMappingsDict.TryGetValue(sourceKey, out var value) || !(value == targetKey)) { totalMappingsDict[sourceKey] = targetKey; SaveTotalMappings(); } } public static string GetMapping(string sourceKey) { GetTotalMappingsDict().TryGetValue(sourceKey, out var value); return value; } public static IRandomReward GetRandomReward() { double num = _globalRng.NextDouble(); float virtualUnlimitedProbability = _virtualUnlimitedProbability; float crestUnlockerProbability = _crestUnlockerProbability; _ = _normalLimitedProbability; if (num < (double)virtualUnlimitedProbability) { if (_unlimitedRewards.Count > 0) { return _unlimitedRewards[_globalRng.Next(_unlimitedRewards.Count)]; } num = (double)virtualUnlimitedProbability + 0.01; } if (num < (double)(virtualUnlimitedProbability + crestUnlockerProbability)) { if (_cachedCrestUnlocker != null && !_cachedCrestUnlocker.IsAtMax()) { return _cachedCrestUnlocker; } num = (double)(virtualUnlimitedProbability + crestUnlockerProbability) + 0.01; } List list = _limitedRewards.Where((IRandomReward r) => r != _cachedCrestUnlocker && !r.IsAtMax()).ToList(); if (list.Count > 0) { return list[_globalRng.Next(list.Count)]; } if (_unlimitedRewards.Count > 0) { return _unlimitedRewards[_globalRng.Next(_unlimitedRewards.Count)]; } return new VirtualReward("virt:FallbackGeo", Locale.Get("保底念珠"), null, delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddGeo(10); } }, () => false); } public static SavedItem GetRandomItem() { List list = _limitedRewards.Where((IRandomReward r) => !r.IsAtMax()).ToList(); if (list.Count == 0) { return null; } IRandomReward randomReward = list[_globalRng.Next(list.Count)]; if (randomReward is SavedItemReward savedItemReward) { return savedItemReward.Item; } ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(randomReward); return (SavedItem)(object)proxySavedItem; } public static SavedItem PeekRandomItem(Random externalRng) { List list = _limitedRewards.OfType().ToList(); if (list.Count == 0) { return null; } return list[externalRng.Next(list.Count)].Item; } public static List GetAllItems() { return (from r in _limitedRewards.OfType() select r.Item into i where (Object)(object)i != (Object)null select i).ToList(); } public static bool GiveRandomReward() { IRandomReward randomReward = GetRandomReward(); if (randomReward == null) { return false; } randomReward.Give(); AddGivenCount(randomReward.Id); return true; } public static void ResetAllData() { GetGivenCountsDict().Clear(); GetTotalMappingsDict().Clear(); SaveGivenCounts(); SaveTotalMappings(); Plugin.Log.LogInfo((object)"所有随机奖励次数和映射表已重置"); } public static string GetSlotTypeName(ToolItemType type) { if (((object)(ToolItemType)(ref type)).ToString().Contains("Attack")) { return Locale.Get("攻击槽"); } if (((object)(ToolItemType)(ref type)).ToString().Contains("Tool") || ((object)(ToolItemType)(ref type)).ToString().Contains("Item")) { return Locale.Get("工具槽"); } if (((object)(ToolItemType)(ref type)).ToString().Contains("Spell")) { return Locale.Get("法术槽"); } return ((object)(ToolItemType)(ref type)).ToString(); } public static void TryUnlockCrestSlot() { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_012b: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) LastUnlockedSlotType = null; PlayerData instance = PlayerData.instance; if (instance == null) { return; } string crestId = instance.CurrentCrestID; if (string.IsNullOrEmpty(crestId)) { List list = new List(); foreach (KeyValuePair item in ((SerializableNamedList)(object)instance.ToolEquips).Enumerate()) { if (item.Value.IsUnlocked) { list.Add(item.Key); } } if (list.Count == 0) { return; } crestId = list[Random.Range(0, list.Count)]; } ToolCrest val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((ToolCrest c) => c.name == crestId)); if ((Object)(object)val == (Object)null) { return; } Data saveData = val.SaveData; if (saveData.Slots == null || saveData.Slots.Count == 0) { saveData.Slots = new List(); for (int i = 0; i < val.Slots.Length; i++) { saveData.Slots.Add(new SlotData { IsUnlocked = !val.Slots[i].IsLocked }); } val.SaveData = saveData; } int num = -1; ToolItemType? lastUnlockedSlotType = null; for (int j = 0; j < saveData.Slots.Count && j < val.Slots.Length; j++) { if (!saveData.Slots[j].IsUnlocked && !((object)(ToolItemType)(ref val.Slots[j].Type)).ToString().Contains("Spell")) { num = j; lastUnlockedSlotType = val.Slots[j].Type; break; } } if (num == -1) { HeroController instance2 = HeroController.instance; if (instance2 != null) { instance2.AddGeo(100); } Plugin.ShowNotification(Locale.Get("纹章槽位已满,获得 100 念珠"), 2f); } else { SlotData value = saveData.Slots[num]; value.IsUnlocked = true; saveData.Slots[num] = value; val.SaveData = saveData; LastUnlockedSlotType = lastUnlockedSlotType; EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); string arg = (lastUnlockedSlotType.HasValue ? GetSlotTypeName(lastUnlockedSlotType.Value) : Locale.Get("未知")); Plugin.ShowNotification(string.Format(Locale.Get("纹章槽位 {0} ({1}) 已解锁!"), num + 1, arg)); } } public static bool IsAllCrestSlotsUnlocked() { //IL_004f: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) PlayerData instance = PlayerData.instance; if (instance == null) { return true; } string crestId = instance.CurrentCrestID; if (string.IsNullOrEmpty(crestId)) { return false; } ToolCrest val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((ToolCrest c) => c.name == crestId)); if ((Object)(object)val == (Object)null) { return false; } Data saveData = val.SaveData; if (saveData.Slots == null || saveData.Slots.Count == 0) { return false; } for (int i = 0; i < saveData.Slots.Count && i < val.Slots.Length; i++) { if (!((object)(ToolItemType)(ref val.Slots[i].Type)).ToString().Contains("Spell") && !saveData.Slots[i].IsUnlocked) { return false; } } return true; } private static bool IsValidItem(SavedItem item) { if (!((Object)(object)item == (Object)null) && !string.IsNullOrEmpty(((Object)item).name)) { return !ExcludedNames.Contains(((Object)item).name); } return false; } } public static class ItemTypeRandomFilter { public static bool EnableCrestRandom { get; private set; } = true; public static bool EnableSkillItemRandom { get; private set; } = true; public static bool EnableRelicRandom { get; private set; } = true; public static void Init(ConfigFile config) { EnableSkillItemRandom = config.Bind("ItemRandom", "EnableSkillItemRandom", true, "是否随机技能类物品(ToolItemSkill 等)").Value; EnableRelicRandom = config.Bind("ItemRandom", "EnableRelicRandom", true, "是否随机遗物(CollectableRelic)").Value; } public static void SetCrestRandomEnabled(bool enabled) { EnableCrestRandom = enabled; } public static void Apply(bool crestEnabled, bool skillItemEnabled, bool relicEnabled) { EnableCrestRandom = crestEnabled; EnableSkillItemRandom = skillItemEnabled; EnableRelicRandom = relicEnabled; } public static bool ShouldRandomize(SavedItem item) { if ((Object)(object)item == (Object)null) { return false; } Type type = ((object)item).GetType(); if (type == typeof(ToolCrest) || type.IsSubclassOf(typeof(ToolCrest))) { return EnableCrestRandom; } if (type == typeof(ToolItemSkill) || type == typeof(ToolItem) || item is ToolItemSkill) { return EnableSkillItemRandom; } if (typeof(CollectableRelic).IsAssignableFrom(type)) { return EnableRelicRandom; } return true; } public static bool ShouldRandomizeCrest() { return EnableCrestRandom; } public static bool ShouldRandomizeRelic() { return EnableRelicRandom; } public static bool ShouldRandomizeSkillItem(SavedItem item) { if ((Object)(object)item == (Object)null) { return false; } Type type = ((object)item).GetType(); if (type == typeof(ToolItemSkill) || type == typeof(ToolItem) || item is ToolItemSkill) { return EnableSkillItemRandom; } return false; } } [HarmonyPatch] public static class PickupPatch { public interface IPickupSaveDataAccessor { HashSet GetPickedPickupKeys(); void SavePickedPickupKeys(HashSet keys); } [CompilerGenerated] private sealed class d__13 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float delay; public Scene scene; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: { <>1__state = -1; Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name == ((Scene)(ref scene)).name) { ApplyStateToScene(scene); Plugin.Log.LogInfo((object)"强制重生:延迟应用拾取点状态完成"); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__20 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CollectableItemPickup pickup; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)pickup != (Object)null) { MarkAsPicked(pickup); Object.Destroy((Object)(object)((Component)pickup).gameObject); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IPickupSaveDataAccessor _saveData; private static bool _isDirty; private static bool _isEnabled; public static void Initialize(IPickupSaveDataAccessor saveDataAccessor) { _saveData = saveDataAccessor; } public static void EnableRandomizer() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!_isEnabled) { _isEnabled = true; DisablePersistentBoolItems(); ApplyStateToScene(SceneManager.GetActiveScene()); Plugin.Log.LogInfo((object)"物品随机器已启用,拾取点已接管"); } } public static void DisableRandomizer() { if (_isEnabled) { _isEnabled = false; RestorePersistentBoolItems(); Plugin.Log.LogInfo((object)"物品随机器已禁用,拾取点已恢复原生行为"); } } public static string GetPickupKey(CollectableItemPickup pickup) { //IL_009f: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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) PersistentBoolItem component = ((Component)pickup).GetComponent(); Scene scene; if ((Object)(object)component != (Object)null) { FieldInfo field = typeof(PersistentBoolItem).GetField("itemData", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(component); if (value != null) { FieldInfo field2 = value.GetType().GetField("ID", BindingFlags.Instance | BindingFlags.Public); if (field2 != null && field2.GetValue(value) is string text && !string.IsNullOrEmpty(text)) { scene = ((Component)pickup).gameObject.scene; return ((Scene)(ref scene)).name + "_" + text; } } } } Vector3 position = ((Component)pickup).transform.position; object[] array = new object[4]; scene = ((Component)pickup).gameObject.scene; array[0] = ((Scene)(ref scene)).name; array[1] = position.x; array[2] = position.y; array[3] = position.z; return string.Format("{0}_{1:F2}_{2:F2}_{3:F2}", array); } private static void SavePickedKeys() { if (_isDirty) { if (_saveData != null) { _saveData.SavePickedPickupKeys(_saveData.GetPickedPickupKeys()); } _isDirty = false; } } private static void DisablePersistentBoolItems() { CollectableItemPickup[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { PersistentBoolItem component = ((Component)array[i]).GetComponent(); if ((Object)(object)component != (Object)null && ((Behaviour)component).enabled) { ((Behaviour)component).enabled = false; } } Plugin.Log.LogInfo((object)"已禁用所有 PersistentBoolItem"); } private static void RestorePersistentBoolItems() { CollectableItemPickup[] array = Resources.FindObjectsOfTypeAll(); for (int i = 0; i < array.Length; i++) { PersistentBoolItem component = ((Component)array[i]).GetComponent(); if ((Object)(object)component != (Object)null && !((Behaviour)component).enabled) { ((Behaviour)component).enabled = true; } } Plugin.Log.LogInfo((object)"已恢复所有 PersistentBoolItem"); } public static void ApplyStateToScene(Scene scene) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (!_isEnabled) { return; } List list = (from p in Resources.FindObjectsOfTypeAll() where ((Component)p).gameObject.scene == scene select p).ToList(); HashSet hashSet = _saveData?.GetPickedPickupKeys() ?? new HashSet(); foreach (CollectableItemPickup item in list) { string pickupKey = GetPickupKey(item); bool flag = hashSet.Contains(pickupKey); ((Component)item).gameObject.SetActive(!flag); } Plugin.Log.LogInfo((object)$"应用拾取点状态: 场景 {((Scene)(ref scene)).name}, 共 {list.Count} 个点, 已捡 {hashSet.Count} 个"); } public static void ApplyStateToSceneWithDelay(Scene scene, float delay = 0.2f) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (_isEnabled) { ApplyStateToScene(scene); if ((Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedApply(scene, delay)); } } } [IteratorStateMachine(typeof(d__13))] private static IEnumerator DelayedApply(Scene scene, float delay) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__13(0) { scene = scene, delay = delay }; } public static void MarkAsPicked(CollectableItemPickup pickup) { if (_isEnabled) { string pickupKey = GetPickupKey(pickup); HashSet hashSet = _saveData?.GetPickedPickupKeys(); if (hashSet != null && hashSet.Add(pickupKey)) { _isDirty = true; SavePickedKeys(); ((Component)pickup).gameObject.SetActive(false); Plugin.Log.LogInfo((object)("标记点为已捡: " + pickupKey)); } } } public static void ResetAll() { (_saveData?.GetPickedPickupKeys())?.Clear(); _isDirty = true; SavePickedKeys(); Plugin.Log.LogInfo((object)"已捡记录已清空,所有拾取点将重新出现"); WarpToLastBench(); } public static void WarpToLastBench() { try { PlayerData instance = PlayerData.instance; if (instance == null) { return; } string respawnScene = instance.respawnScene; if (string.IsNullOrEmpty(respawnScene)) { return; } Plugin.Log.LogInfo((object)("[Warp] 传送至重生点: " + respawnScene)); GameManager gm = GameManager.instance; gm.SaveGame((Action)delegate(bool success) { if (success) { gm.LoadGameFromUI(gm.profileID); } }); } catch (Exception arg) { Plugin.Log.LogError((object)$"传送失败: {arg}"); } } [HarmonyPatch(typeof(CollectableItemPickup), "CheckActivation")] [HarmonyPrefix] private static bool Prefix_CheckActivation(CollectableItemPickup __instance) { if (!_isEnabled) { return true; } return false; } [HarmonyPatch(typeof(CollectableItemPickup), "SetPlayerDataBool")] [HarmonyPrefix] private static bool Prefix_SetPlayerDataBool(CollectableItemPickup __instance, string boolName) { if (!_isEnabled) { return true; } return false; } [HarmonyPatch(typeof(CollectableItemPickup), "DoPickupAction")] [HarmonyPrefix] private static void Prefix_DoPickupAction(CollectableItemPickup __instance, ref bool __runOriginal) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) try { if (__runOriginal && !((Object)(object)__instance == (Object)null) && _isEnabled) { SavedItem item = __instance.Item; if (!((Object)(object)item == (Object)null) && !ItemRandomizer.ExcludedNames.Contains(((Object)item).name)) { object[] array = new object[4]; Scene scene = ((Component)__instance).gameObject.scene; array[0] = ((Scene)(ref scene)).name; array[1] = ((Component)__instance).transform.position.x; array[2] = ((Component)__instance).transform.position.y; array[3] = ((Component)__instance).transform.position.z; Plugin.AddDestroyedPickupKey(string.Format("{0}_{1:F1}_{2:F1}_{3:F1}", array)); item.TryGet(false, true); ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedCleanup(__instance)); __runOriginal = false; } } } catch (Exception arg) { Plugin.Log.LogError((object)$"PickupPatch.Prefix 出错: {arg}"); } } [IteratorStateMachine(typeof(d__20))] private static IEnumerator DelayedCleanup(CollectableItemPickup pickup) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0) { pickup = pickup }; } [HarmonyPatch(typeof(CollectableItemPickup), "DoPickupAction")] [HarmonyPostfix] private static void Postfix_DoPickupAction(CollectableItemPickup __instance) { } public static bool IsKeyPicked(string key) { if (!_isEnabled) { return false; } return (_saveData?.GetPickedPickupKeys())?.Contains(key) ?? false; } } [BepInPlugin("YourName.SilksongItemRandomizer", "Silksong Item Randomizer", "1.0.0.0")] public class Plugin : BaseUnityPlugin { [CompilerGenerated] private sealed class d__50 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Scene scene; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__50(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: { <>1__state = -1; CollectableItemPickup[] array = Resources.FindObjectsOfTypeAll(); foreach (CollectableItemPickup val in array) { if (!(((Component)val).gameObject.scene != scene)) { string text = $"{((Scene)(ref scene)).name}_{((Component)val).transform.position.x:F1}_{((Component)val).transform.position.y:F1}_{((Component)val).transform.position.z:F1}"; if (SaveData.DestroyedPickupKeys.Contains(text)) { Object.Destroy((Object)(object)((Component)val).gameObject); Log.LogInfo((object)("场景加载时销毁已标记点: " + text)); } } } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__46 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__46(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; if (SaveData.TrapEnabled) { Log.LogInfo((object)"陷阱随机系统已由 API 初始化"); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__44 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private GameManager 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__44(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__2 = null; goto IL_0051; case 1: <>1__state = -1; goto IL_0051; case 2: <>1__state = -1; goto IL_0078; case 3: { <>1__state = -1; SilksongItemRandomizerAPI.MarkGameReady(); ItemRandomizer.Initialize(RandomSeed.Value, null, new SilksongItemRandomizerAPI.PluginSaveDataAccessor(), fullRandomMode: false); CrestRandomizer.Initialize(RandomSeed.Value, CrestRandomEnabled.Value, new SilksongItemRandomizerAPI.CrestSaveDataAccessor()); Log.LogInfo((object)$"Randomizer initialized with seed: {RandomSeed.Value}"); ItemLocalizationRegistrar.RegisterAllKnownItems(); return false; } IL_0051: if ((Object)(object)5__2 == (Object)null) { 5__2 = Object.FindObjectOfType(); <>2__current = null; <>1__state = 1; return true; } goto IL_0078; IL_0078: if (string.IsNullOrEmpty(5__2.sceneName)) { <>2__current = null; <>1__state = 2; return true; } <>2__current = null; <>1__state = 3; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__49 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__49(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 1; return true; case 1: <>1__state = -1; TrapRandomizer.SpawnTraps(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static ManualLogSource Log; private static string _notificationMessage; private static float _notificationEndTime; private static GUIStyle _notificationStyle; private static Texture2D _bgTex; private Harmony _harmonyItem; private static readonly string GlobalSavePath = Path.Combine(Paths.ConfigPath, "SilksongItemRandomizer", "global_save.json"); public static ConfigEntry CrestRandomEnabled { get; private set; } public static ConfigEntry RandomSeed { get; private set; } public static ConfigEntry ItemRandomEnabled { get; private set; } public static Plugin Instance { get; private set; } public static ConfigEntry SilkRandomizerEnabled { get; private set; } public static ConfigEntry SilkRandomMin { get; private set; } public static ConfigEntry SilkRandomMax { get; private set; } public static GlobalSaveData SaveData { get; private set; } public static bool PublicItemRandomEnabled { get { return ItemRandomEnabled.Value; } set { if (ItemRandomEnabled.Value != value) { ItemRandomEnabled.Value = value; ((BaseUnityPlugin)Instance).Config.Save(); SilksongItemRandomizerAPI.SetEnabled(value); } } } public static void ResetSaveData() { SaveData = new GlobalSaveData(); SaveGlobalData(); } private void Awake() { //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Expected O, but got Unknown //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; RandomSeed = ((BaseUnityPlugin)this).Config.Bind("General", "RandomSeed", 0, "随机种子 (0 表示随机)"); ItemRandomEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "ItemRandomEnabled", true, "Enable/disable item randomization"); CrestRandomEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "CrestRandomEnabled", true, "启用纹章随机(独立开关,仅在物品随机总开关开启时生效)"); SilkRandomizerEnabled = ((BaseUnityPlugin)this).Config.Bind("Silk Randomizer", "Enabled", true, "启用灵丝获得/消耗随机化"); SilkRandomMin = ((BaseUnityPlugin)this).Config.Bind("Silk Randomizer", "MinAmount", 1, "随机获得/消耗的最小灵丝数量(1-9)"); SilkRandomMax = ((BaseUnityPlugin)this).Config.Bind("Silk Randomizer", "MaxAmount", 9, "随机获得/消耗的最大灵丝数量(1-9)"); LoadGlobalData(); ItemLimitConfig.Init(((BaseUnityPlugin)this).Config); ItemTypeRandomFilter.Init(((BaseUnityPlugin)this).Config); ItemTypeRandomFilter.SetCrestRandomEnabled(CrestRandomEnabled.Value); SilksongItemRandomizerAPI.Initialize(new ItemRandomizerConfig { Seed = RandomSeed.Value, Enabled = ItemRandomEnabled.Value, CrestEnabled = CrestRandomEnabled.Value, TrapEnabled = SaveData.TrapEnabled, TrapMovementEnabled = SaveData.TrapMovementEnabled, TrapDifficulty = ParseTrapDifficulty(SaveData.TrapDifficulty), CrestRandomEnabled = CrestRandomEnabled.Value, SkillItemRandomEnabled = ItemTypeRandomFilter.EnableSkillItemRandom, RelicRandomEnabled = ItemTypeRandomFilter.EnableRelicRandom, CurrencyFirstThreshold = SaveData.CurrencyFirstThreshold, CurrencySecondThreshold = SaveData.CurrencySecondThreshold, SilkSpearPityCount = SaveData.SilkSpearPityCount, Limits = new ItemLimitSettings { SkillItem = ItemLimitConfig.LimitSkillItem, Relic = ItemLimitConfig.LimitRelic, OtherItem = ItemLimitConfig.LimitOtherItem, UpSlash = ItemLimitConfig.LimitUpSlash, LeftSlash = ItemLimitConfig.LimitLeftSlash, RightSlash = ItemLimitConfig.LimitRightSlash, DashLeft = ItemLimitConfig.LimitDashLeft, DashRight = ItemLimitConfig.LimitDashRight, HarpoonLeft = ItemLimitConfig.LimitHarpoonLeft, HarpoonRight = ItemLimitConfig.LimitHarpoonRight, FloatLeft = ItemLimitConfig.LimitFloatLeft, FloatRight = ItemLimitConfig.LimitFloatRight, WallJumpLeft = ItemLimitConfig.LimitWallJumpLeft, WallJumpRight = ItemLimitConfig.LimitWallJumpRight, Heal = ItemLimitConfig.LimitHeal, NeedleThrow = ItemLimitConfig.LimitNeedleThrow, ThreadSphere = ItemLimitConfig.LimitThreadSphere, HarpoonDash = ItemLimitConfig.LimitHarpoonDash, SilkCharge = ItemLimitConfig.LimitSilkCharge, SilkBomb = ItemLimitConfig.LimitSilkBomb, SilkBossNeedle = ItemLimitConfig.LimitSilkBossNeedle, Needolin = ItemLimitConfig.LimitNeedolin, Parry = ItemLimitConfig.LimitParry, NeedolinMemory = ItemLimitConfig.LimitNeedolinMemory, FastTravel = ItemLimitConfig.LimitFastTravel, EvaHeal = ItemLimitConfig.LimitEvaHeal, Dash = ItemLimitConfig.LimitDash, Brolly = ItemLimitConfig.LimitBrolly, DoubleJump = ItemLimitConfig.LimitDoubleJump, SuperJump = ItemLimitConfig.LimitSuperJump, WallJump = ItemLimitConfig.LimitWallJump, ChargeSlash = ItemLimitConfig.LimitChargeSlash, HeartPiece = ItemLimitConfig.LimitHeartPiece, SpoolPart = ItemLimitConfig.LimitSpoolPart, MaxSilkRegenUp = ItemLimitConfig.LimitMaxSilkRegenUp, UnlockCrestSlot = ItemLimitConfig.LimitUnlockCrestSlot }, InfinitePool = new InfinitePoolSettings { Silk = ItemLimitConfig.EnableInfSilk, FullRestore = ItemLimitConfig.EnableInfFullRestore, BlueHealth = ItemLimitConfig.EnableInfBlueHealth, Geo300 = ItemLimitConfig.EnableInfGeo300, Shards300 = ItemLimitConfig.EnableInfShards300, SilkParts = ItemLimitConfig.EnableInfSilkParts } }); _harmonyItem = new Harmony("SilksongItemRandomizer.ItemPatches"); ItemRandomEnabled.SettingChanged += delegate { SilksongItemRandomizerAPI.SetEnabled(ItemRandomEnabled.Value); }; CrestRandomEnabled.SettingChanged += delegate { SilksongItemRandomizerAPI.SetCrestEnabled(CrestRandomEnabled.Value); }; _bgTex = MakeTexture(2, 2, new Color(0f, 0f, 0f, 0.7f)); Extracurrencypickup.RegisterAll(); ((MonoBehaviour)this).StartCoroutine(InitializeAfterLoad(RandomSeed.Value)); SceneManager.sceneLoaded += OnSceneLoaded; ((MonoBehaviour)this).StartCoroutine(InitTrapsAfterLoad()); Harmony.CreateAndPatchAll(typeof(HeroRespawnReset), (string)null); GameObject val = new GameObject("SilksongItemRandomizer_HotkeyHandler"); Object.DontDestroyOnLoad((Object)val); val.AddComponent(); Log.LogInfo((object)"Plugin SilksongItemRandomizer loaded (global save integrated)"); } [IteratorStateMachine(typeof(d__44))] private IEnumerator InitializeAfterLoad(int seed) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__44(0); } public void ApplyItemPatches() { if (!ItemRandomEnabled.Value) { return; } _harmonyItem.PatchAll(typeof(PickupPatch)); _harmonyItem.PatchAll(typeof(CurrencyCollectPatch)); _harmonyItem.PatchAll(typeof(TryGetPatch)); _harmonyItem.PatchAll(typeof(CrestRandomizePatch)); CrestRandomizePatch.Initialize(new SilksongItemRandomizerAPI.PluginSaveDataAccessor()); _harmonyItem.PatchAll(typeof(ShopMenuStock_BuildItemList_Patch)); ShopMenuStock_BuildItemList_Patch.Initialize(new SilksongItemRandomizerAPI.PluginSaveDataAccessor()); _harmonyItem.PatchAll(typeof(ShopItemStats_Purchase_Patch)); _harmonyItem.PatchAll(typeof(SilkSpearPityPatch)); SilkSpearPityPatch.Initialize(new SilksongItemRandomizerAPI.PluginSaveDataAccessor()); _harmonyItem.PatchAll(typeof(BenchRespawnPatch)); BenchRespawnPatch.Initialize(new SilksongItemRandomizerAPI.PluginSaveDataAccessor()); _harmonyItem.PatchAll(typeof(SilkRandomizerPatch)); _harmonyItem.PatchAll(typeof(Extracurrencypickup)); Extracurrencypickup.Initialize(new SilksongItemRandomizerAPI.PluginSaveDataAccessor()); try { EnemyRandoAdjuster.TryPatch(_harmonyItem); } catch (Exception ex) { Log.LogWarning((object)("EnemyRandoAdjuster 补丁跳过(可能缺少 EnemyRando): " + ex.Message)); } } [IteratorStateMachine(typeof(d__46))] private IEnumerator InitTrapsAfterLoad() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__46(0); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; SaveGlobalData(); } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (ItemRandomEnabled.Value) { PickupPatch.ApplyStateToSceneWithDelay(scene); } Extracurrencypickup.SpawnPickupsForScene(scene); ((MonoBehaviour)this).StartCoroutine(DestroyMarkedPickups(scene)); if (SaveData.TrapEnabled && ((Scene)(ref scene)).name != "Menu_Title" && ((Scene)(ref scene)).name != "Menu" && ((Scene)(ref scene)).name != "Loading") { TrapRandomizer.ClearAndRescan(); ((MonoBehaviour)this).StartCoroutine(SpawnTrapsAfterSceneLoad()); } } [IteratorStateMachine(typeof(d__49))] private IEnumerator SpawnTrapsAfterSceneLoad() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__49(0); } [IteratorStateMachine(typeof(d__50))] private IEnumerator DestroyMarkedPickups(Scene scene) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__50(0) { scene = scene }; } private void Update() { RecentItemsUI.UpdateAutoHide(); } private void OnGUI() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown try { RecentItemsUI.Draw(); if (_notificationMessage != null && Time.time <= _notificationEndTime) { if (_notificationStyle == null) { GUIStyle val = new GUIStyle(GUI.skin.box) { fontSize = 40, alignment = (TextAnchor)4 }; val.normal.textColor = Color.white; val.normal.background = _bgTex; _notificationStyle = val; } float num = ((float)Screen.width - 600f) / 2f; int num2 = Screen.height / 2 - 100; GUI.Box(new Rect(num, (float)num2, 600f, 120f), _notificationMessage, _notificationStyle); } else { _notificationMessage = null; } } catch { } } public void DumpAllMappings() { //IL_0166: Unknown result type (might be due to invalid IL or missing references) int value = RandomSeed.Value; Log.LogInfo((object)$"===== 当前种子: {value} ====="); List crestList = CrestRandomizer.CrestList; if (crestList != null && crestList.Count > 0) { Log.LogInfo((object)"--- 纹章映射 (来自外部存储) ---"); foreach (ToolCrest item2 in crestList) { Log.LogInfo((object)(" " + item2.name + " -> " + CrestRandomizer.GetMappedCrestName(item2.name))); } } else { Log.LogInfo((object)"--- 未找到纹章 ---"); } Log.LogInfo((object)"--- 当前场景拾取点映射 ---"); List list = Resources.FindObjectsOfTypeAll().Where(delegate(CollectableItemPickup p) { //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) Scene scene = ((Component)p).gameObject.scene; return ((Scene)(ref scene)).isLoaded; }).ToList(); if (list.Count == 0) { Log.LogInfo((object)"当前场景无拾取点。"); } else { foreach (CollectableItemPickup item3 in list) { SavedItem item = item3.Item; if (!((Object)(object)item == (Object)null)) { SavedItem val = ItemRandomizer.PeekRandomItem(new Random(value + ((Object)item3).GetInstanceID())); if ((Object)(object)val != (Object)null) { Log.LogInfo((object)$" {((Object)item).name} (位置 {((Component)item3).transform.position}) -> {((Object)val).name}"); } else { Log.LogInfo((object)(" " + ((Object)item).name + " -> 随机失败")); } } } } Log.LogInfo((object)"==============================="); } public static void ShowNotification(string message, float duration = 3f) { _notificationMessage = message; _notificationEndTime = Time.time + duration; } private Texture2D MakeTexture(int width, int height, Color col) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[width * height]; for (int i = 0; i < array.Length; i++) { array[i] = col; } Texture2D val = new Texture2D(width, height); val.SetPixels(array); val.Apply(); return val; } private void LoadGlobalData() { try { if (File.Exists(GlobalSavePath)) { SaveData = JsonConvert.DeserializeObject(File.ReadAllText(GlobalSavePath)) ?? new GlobalSaveData(); Log.LogInfo((object)$"加载全局数据成功,版本 {SaveData.Version}"); } else { SaveData = new GlobalSaveData(); Log.LogInfo((object)"未找到全局存档,创建新存档"); } if (SaveData.Version < 2) { SaveData.VirtualUnlimitedProbability = 0.1f; SaveData.CrestUnlockerProbability = 0.1f; SaveData.NormalLimitedProbability = 0.8f; SaveData.MaxGivenPerItem = 2; SaveData.CurrencyFirstThreshold = 30; SaveData.CurrencySecondThreshold = 1000; SaveData.SilkSpearPityCount = 10; SaveData.Version = 2; SaveGlobalData(); Log.LogInfo((object)"已为旧存档添加物品随机配置默认值"); } } catch (Exception arg) { Log.LogError((object)$"加载全局数据失败: {arg}"); SaveData = new GlobalSaveData(); } } public static void SaveGlobalData() { try { string directoryName = Path.GetDirectoryName(GlobalSavePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } string contents = JsonConvert.SerializeObject((object)SaveData, (Formatting)1); File.WriteAllText(GlobalSavePath, contents); } catch (Exception arg) { Log.LogError((object)$"保存全局数据失败: {arg}"); } } public static void AddDestroyedPickupKey(string key) { SaveData.DestroyedPickupKeys.Add(key); SaveGlobalData(); } public static void ResetDestroyedPickupKeys() { SaveData.DestroyedPickupKeys.Clear(); SaveGlobalData(); } public static void ResetAllStaticData() { SilksongItemRandomizerAPI.ResetAllData(); RandomSeed.Value = 0; Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Config.Save(); } Log.LogInfo((object)"物品随机MOD所有静态数据已重置,随机系统已重新初始化,并传送回椅子"); } private int ParseTrapDifficulty(string difficultyStr) { if (string.IsNullOrEmpty(difficultyStr)) { return 0; } return difficultyStr switch { "Beginner" => 0, "Focused" => 1, "Overflow" => 2, _ => 0, }; } public static void OverrideBenchwarpLanguage() { } public void RefreshBenchwarpUI() { } } public static class PrefabIdList { public static readonly List AllIds = new List { "abyss_pod", "abyss_plat_mid", "abyss_plat_wide", "abyss_tablet", "abyss_tendrils", "abyss_water", "alita", "ant_string_shard", "ant_trap_cage", "aspid_bullet", "aspid_collector", "aspid_glob", "aspid_hatchling", "beastfly", "bell_bench", "bell_bench_full", "bell_bomb", "bell_bullet", "bell_lock", "bell_plat_1", "bell_plat_2", "bell_plat_3", "bell_s", "bellbeast_child", "bellhome_bed", "bile_gate", "bilewater_trap", "bind_source", "bind_source_stand", "black_strand", "black_thread_effect", "black_thread_strand", "bloat_roach", "bloom_puncher", "bloom_shooter", "blur_plane", "body_sack", "bone_boulder", "bone_chest", "bone_circler", "bone_circler_v", "bone_crawler", "bone_crawler_summon", "bone_goomba", "bone_goomba_bounce_fly", "bone_goomba_l", "bone_goomba_skull", "bone_goomba_skull_large", "bone_hunter", "bone_hunter_buzzer", "bone_hunter_child", "bone_hunter_fly", "bone_hunter_throw", "bone_hunter_tiny", "bone_lever", "bone_plat_01", "bone_plat_02", "bone_plat_crumble_1", "bone_plat_crumble_2", "bone_plat_crumble_3", "bone_plat_crumble_4", "bone_roller", "bone_thumper", "boom_rock_fall", "bounce_bloom", "bounce_flea", "bounce_pod", "breakable_wall", "breakable_wall_2", "breakable_window", "brown_vines", "brushflit", "bubble_brazier_effect", "bubble_lantern_effect", "caltrop", "caltrop_ball", "caravan_lech_wounded", "caretaker", "catalyst", "celeste_bumper", "choir_bomb_l", "choir_bomb_s", "choir_flyer", "choristor", "citadel_button", "citadel_button_big", "citadel_gate", "citadel_gate_big", "citadel_lamp", "citadel_plat_1", "citadel_plat_2", "citadel_plat_3", "citadel_plat_4", "clawmaiden", "clover_pod", "clover_pod_activator", "clover_statue", "cloverstag", "coal_lamp", "cog_clapper", "cog_lever", "cog_plat_1", "cog_plat_2", "cogwork_defender", "cogwork_spine", "cogworker", "collapser_rock", "collapser_under", "confetti_burst", "coral_bubble", "coral_conch_driller", "coral_conch_shooter", "coral_conch_shooter_heavy", "coral_crust_l", "coral_crust_m", "coral_crust_s", "coral_crust_tree_activator", "coral_crust_tree_branch", "coral_furm", "coral_gate", "coral_goomba_l", "coral_goomba_m", "coral_goomba_xl", "coral_lightning_orb", "coral_lightning_rock", "coral_nut", "coral_plat_float", "coral_poke_swimmer", "coral_spike", "coral_spike_fall", "coral_spike_goomba", "coral_spike_swimmer", "coral_swimmer_fat", "coral_swimmer_small", "coral_tablet", "coral_warrior", "corrcrust_karaka", "covetous_pilgrim", "craggler", "cragglite", "cradle_nut", "cradle_plat", "cradle_spiked_plat", "cradle_spikes", "craw_chain", "craw_juror", "crawfather", "crest_ability", "crest_tool", "cross_bomb", "crown", "crumbling_rocks_1", "crumbling_rocks_2", "crumbling_underworks", "crust_king", "crystal_drifter", "crystal_drifter_giant", "dejected_pilgrim", "deep_diver", "deepnest_platform_01", "deepnest_platform_02", "deepnest_platform_03", "deepnest_platform_04", "deepnest_platform_05", "dial_door", "disgraced_chef", "dock_bomber", "dock_charger", "dock_flyer", "dock_plat_01", "dock_plat_02", "dock_worker", "dodge_flea", "drapelord", "drapemite", "drapefly", "driznit", "driznarga", "ductsucker", "dust_effect", "dust_trap_spike_dropper", "dust_trap_spike_plate", "elder_pilgrim", "emerge_dust", "enviro_region", "envoy", "escalion", "exploding_wall", "explosion", "falling_bell", "falling_lava", "falling_mossgrub", "falling_spike_ball", "fan_hazard", "farmer_wisp", "fayforn_npc", "feather_effect", "fertid", "fifth_chorus", "first_sinner", "fish_effect", "fixer_statue", "flapping_fertid", "flea_1", "flea_counter", "fleamaster_npc", "flick_npc", "flick_statue", "flint_beetle", "flint_bomb", "flintbomb", "flintflame_bomb", "flintflame_flyer", "flintrock", "flintstone_flyer", "float_crystal", "floating_coldshard", "flower_drifter", "flower_drifter_hidden", "flowing_water_effect", "fly_spit", "fly_swarm_effect", "forebrother_gron", "forebrother_signis", "forge_daughter_npc", "fourth_chorus", "freshfly", "frost_marker", "fung_plat_float_01", "fung_plat_float_02", "furm", "gargant_gloom", "garmond_zaza", "garmond_zaza_boss", "garpid", "giant_drapemite", "gilly_npc", "gloomsac", "gold_ring", "gong", "grand_reed", "grass_effect", "green_prince", "greymoor_balloon_large", "greymoor_balloon_mid", "greymoor_balloon_small", "greymoor_flip_bridge", "greymoor_lamp", "greymoor_plat_1", "grind_plat", "groal", "groal_fireball", "grom", "gromling", "grove_pilgrim", "grove_pilgrim_hatchling", "growing_coral_platform_1", "growing_coral_platform_2", "growing_coral_platform_3", "growing_coral_platform_4", "guardfly", "gurr_trap", "hang_bell", "hang_bell_citadel", "hardbone_elder", "hardbone_hopper", "harp_ring", "harpoon_ring", "harpoon_ring_citadel", "harpoon_ring_h", "harpoon_ring_pinstress", "harpoon_ring_v", "health_cocoon", "heat_effect", "heavy_sentry", "hero_wisp_fireball", "hive_platform_01", "hive_platform_02", "hive_platform_03", "hive_pod", "hoker", "hoker_spine", "hornet_cocoon", "hot_coal", "hot_coals", "huge_flea", "humble_pilgrim", "hunter_landmine", "hunter_sickle_trap", "hunter_trap_plate", "hunterfruit", "imoba", "jail_gate_door", "jail_lever", "javelin_attack", "jelly_egg", "judge", "judge_statue", "junk_pipe", "kai", "karak_gor", "karaka_statue", "karmelita", "kilik", "kindanir", "knight_attack", "kratt", "lamp_attack", "lampbearer", "large_bell", "large_citadel_chest", "large_gold_cog", "large_grey_cog", "large_red_coral_plat", "large_skull", "last_claw", "last_judge", "lava_area", "lava_crumble_plat", "lava_crumble_plat_b", "lavalarga", "lavalug", "leaf_glider", "leaf_roller", "life_pustule", "lifeblood_shot", "lilypad", "loam_npc", "lost_garmond", "magma_rocks", "maggot_effect", "maggot_sack", "maestro", "mapper_pole", "mapper_ring", "march_pogo", "march_ring", "marrow_plat_01", "marrow_plat_02", "marrowmaw", "marrowmaw_statue", "mask_maker_npc", "mask_shard", "massive_mossgrub", "memoria", "memorium_plat_1", "memorium_plat_2", "memory_ground_plat", "memory_silk_effect", "metronome_plat", "mid_red_coral_plat", "mill_trap", "minister", "mirror_effect", "mist_silkfly", "mite", "mite_trap", "mitefly", "mitemother", "mnemonid", "mnemonord", "moor_plat_1", "moorwing", "mortician", "moss_ball", "moss_ball_break", "moss_cocoon", "moss_crumble_plat", "moss_grotto_plat_1", "moss_mother", "mothleaf", "muck_pod", "muckroach", "mushroom_tablet", "needolin_gate", "organ_plat_1", "organ_plat_2", "organ_plat_3", "organ_spikes", "overgrown_pilgrim", "pavo_normal", "pavo_sad", "peak_drifter", "pendra", "pendragor", "penitent", "petrified_pilgrim_1", "petrified_pilgrim_2", "phantom", "pharlid", "pharlid_diver", "pilby_death", "pilgrim_01", "pilgrim_02", "pilgrim_03", "pilgrim_04", "pilgrim_bell", "pilgrim_bellthrower_fly", "pilgrim_dummy_1", "pilgrim_dummy_2", "pilgrim_dummy_3", "pilgrim_fisher", "pilgrim_fly", "pilgrim_guide", "pilgrim_hiker", "pilgrim_hornfly", "pilgrim_hulk", "pilgrim_moss_spitter", "pilgrim_preacher", "pilgrim_stomper_song", "pilgrim_trap_spike", "pilgrim_trap_wire", "pilgrim_wingbell", "pin_pilgrim_npc", "pitchfork", "plasmid", "plasmidas", "plasmified_zango", "pokenabbin", "pollen_effect", "pollen_flare", "pollenica", "pond_skipper", "pond_skipper_body", "pondcatcher", "preacher", "pressure_plate_trap", "puny_penitent", "quiet_pilgrim", "rag_balloon_l", "rag_balloon_m", "rag_balloon_s", "rain_dots_effect", "rain_effect", "red_coral_spike", "reed", "reflection_effect", "reusable_cog_lever", "reusable_lever", "rhinogrund", "ring_switch", "roachcatcher", "roachfeeder", "roachkeeper", "roachserver", "rosary", "rosary_bell", "rosary_shrine_small", "rosary_toll", "rubble_field", "rune_bomb", "rune_rage", "sand_effect", "sandcarver_group", "savage_beastfly", "scabfly", "scared_pilgrim", "scarecraw", "score_counter", "scrollreader", "second_sentinel_ally", "second_sentinel_boss", "servitor_blast", "servitor_ignim", "servitor_large", "seth_npc", "shadow_charger", "shadow_creeper", "shakra", "shakra_boss", "shakra_lamp", "shaman_shell_l", "shaman_shell_m", "shaman_shell_s", "shard_statue_1", "shard_statue_2", "shard_statue_3", "shardillard", "shell_small", "shellwood_gnat", "shellwood_gnat_core", "shellwood_gnat_fly", "shellwood_thorns", "sherma_1", "sherma_2", "shield_dockworker", "sickle_attack_l", "sickle_attack_s", "sickle_trap", "silk_acid", "silk_acid_cloud", "silk_heart", "silk_lever", "silk_pod", "silk_snipper", "silk_spool_take", "silk_vines", "silkcatcher_plant", "silkdew", "silkeater", "silkeater_hang", "silkeater_s_hang", "silkfly", "silkfly_ambient", "silhouette_effect", "skarr_cage", "skarr_javelin", "skarr_pressure_plate", "skarr_scout", "skarr_stalker", "skarr_string_l", "skarr_string_m", "skarr_string_s", "skarrgard", "skarrsinger_karmelita", "skrill", "skull_brute", "skull_scuttler", "skull_tyrant", "skullwing", "slab_jailer", "slab_lever", "slab_pressure_plate", "slab_prob_blade", "slab_spike_ball", "slab_trap", "slammer", "slasher", "sleeping_flea", "slope_area", "small_bell", "small_cog", "small_grey_coral_plat", "small_red_coral_plat", "smelt_shoveller", "smokerock_sifter", "snitchfly", "snow_chunk", "snow_effect", "song_auto_1", "song_auto_2", "song_auto_crawl", "song_auto_heavy", "song_chest", "song_lever_side", "song_maestro", "song_pilgrim_01", "song_pilgrim_02", "song_pilgrim_03", "song_reed", "song_reed_grand", "spa_area", "spear_skarr", "spike_ball", "spike_cog_1", "spike_cog_2", "spike_cog_3", "spike_cog_4", "spike_cog_5", "spine_floater", "spinebeak_kai", "splash_effect", "splinter", "splinterbark", "splinterhorn", "spool_fragment", "sprintmaster_pod", "squatcraw", "squatcraw_juror", "squirm", "stake_trap", "steam_gate", "steam_vent", "steel_seer", "stilkin", "stilkin_trapper", "stilkin_trapper_dart", "stomp_spire", "summoned_saviour", "surface_dust", "surface_scuttler", "surface_water_effect", "surgeon", "swap_bounce_pod", "swamp_barnacle", "swamp_barnacle_slab_fly", "swamp_ductsucker", "swamp_goomba", "swamp_mosquito", "swamp_mosquito_skinny", "swamp_plat_1", "swamp_plat_2", "sway_effect", "tallcraw", "tallcraw_juror", "tar_slug", "tar_slug_huge", "tarmite", "thread_effect", "thread_raker", "thread_storm", "throwing_bell", "toll_bench", "tormented_trobbibomb", "tormented_trobbiwork", "tormented_trobbio", "treadmill", "trobbibomb", "trobbiwork", "trobbio", "trobbio_sign", "trobbio_tornado", "trobbinado", "twelfth_architect", "under_plat_1", "undercrank", "underloft", "underpoke", "underscrub", "undersweep", "underworker", "updraft_region", "vault_lamp", "vault_w_lamp", "vaultborn", "vaultkeeper", "ventrica_tube", "verdania_button", "verdania_gate", "verdania_lamp", "verdania_plat_1", "verdania_plat_2", "verdania_plat_3", "verdanir", "vertical_moving_ring", "vicious_caranid", "vignette_cutout_effect", "void_bullet", "void_glob", "void_mass_citadel", "void_shot", "void_tsunami", "void_wave", "voltbeam", "voltbola", "voltgrass", "voltring", "wardenfly", "water_area", "water_effect", "water_effect_anim", "water_waterfall_tiled", "waterfall_a", "waterfall_b", "waterfall_c", "waterfall_d", "watcher_at_the_edge", "weaver_gate", "weaver_heat_lamp", "weaver_heat_lamp_l", "weaver_harp_sign", "weaver_harp_sign_double", "weaver_lift", "weaver_plat_1", "weaver_plat_2", "web_effect", "white_palace_fly", "white_thorns", "winged_furm", "winged_lifeseed", "winged_pilgrim_bellbearer", "wisp", "wisp_bounce_pod", "wisp_flame_lantern", "wood_plat_1", "wood_plat_2", "wooden_gate", "worm_plat_1", "worried_pilgrim", "wraith", "yago", "yuma", "yumama", "zango_boss" }; } public static class RecentItemsUI { [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawWindow; } private static readonly Queue RecentRewards = new Queue(); private const int MaxItems = 5; private static Rect _windowRect = new Rect(20f, 300f, 700f, 600f); private static bool _showWindow; private static float _hideTime; private static readonly Dictionary _iconCache = new Dictionary(); private static Sprite _defaultFallbackIcon; public static bool IsVisible => _showWindow; public static void AddItem(SavedItem item) { AddItem((IRandomReward)new SavedItemReward(item)); } public static void AddItem(IRandomReward reward) { if (reward != null) { RecentRewards.Enqueue(reward); while (RecentRewards.Count > 5) { RecentRewards.Dequeue(); } _showWindow = true; _hideTime = Time.time + 10f; } } public static void Toggle() { _showWindow = !_showWindow; if (_showWindow) { _hideTime = float.MaxValue; } } public static void UpdateAutoHide() { if (_showWindow && Time.time >= _hideTime) { _showWindow = false; } } public static void Draw() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if (_showWindow) { Rect windowRect = _windowRect; object obj = <>O.<0>__DrawWindow; if (obj == null) { WindowFunction val = DrawWindow; <>O.<0>__DrawWindow = val; obj = (object)val; } _windowRect = GUILayout.Window(999, windowRect, (WindowFunction)obj, Locale.Get("最近获得物品"), Array.Empty()); } } private static void DrawWindow(int id) { int fontSize = GUI.skin.label.fontSize; GUI.skin.label.fontSize = 32; GUILayout.BeginVertical(Array.Empty()); foreach (IRandomReward item in RecentRewards.ToList()) { try { DrawRewardItem(item); } catch (Exception ex) { Plugin.Log.LogError((object)("绘制奖励失败: " + item?.Id + " - " + ex.Message)); GUILayout.Label("❌ 显示错误", Array.Empty()); } } GUILayout.EndVertical(); GUI.DragWindow(); GUI.skin.label.fontSize = fontSize; } private static void DrawRewardItem(IRandomReward reward) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); Sprite val = GetIconForReward(reward); if ((Object)(object)val == (Object)null) { val = GetDefaultFallbackIcon(); } float num = 96f; float num2 = 96f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(0f, 0f, 1f, 1f); if ((Object)(object)val != (Object)null && (Object)(object)val.texture != (Object)null) { Rect textureRect = val.textureRect; float num3 = ((Texture)val.texture).width; float num4 = ((Texture)val.texture).height; ((Rect)(ref val2))..ctor(((Rect)(ref textureRect)).x / num3, ((Rect)(ref textureRect)).y / num4, ((Rect)(ref textureRect)).width / num3, ((Rect)(ref textureRect)).height / num4); if (((Rect)(ref textureRect)).width > 0f && ((Rect)(ref textureRect)).height > 0f) { num2 = num * (((Rect)(ref textureRect)).height / ((Rect)(ref textureRect)).width); if (num2 > 180f) { num2 = 180f; } } } Rect rect = GUILayoutUtility.GetRect(num, num2, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(num), GUILayout.Height(num2) }); if ((Object)(object)val != (Object)null && (Object)(object)val.texture != (Object)null) { GUI.DrawTextureWithTexCoords(rect, (Texture)(object)val.texture, val2); } else { GUI.Box(rect, ""); GUI.Label(rect, "?", new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 36 }); } string text; try { text = reward.DisplayName; } catch { text = reward.Id; } GUILayout.Label("• " + text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num2) }); GUILayout.EndHorizontal(); } private static Sprite GetIconForReward(IRandomReward reward) { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) if (reward is SavedItemReward savedItemReward) { try { return savedItemReward.Icon; } catch { return null; } } if (_iconCache.TryGetValue(reward.Id, out var value)) { return value; } Sprite val = null; string displayName = reward.DisplayName; if (displayName.Contains(Locale.Get("灵丝"))) { val = FindSprite("silk_heart_inv_icon"); } else if (displayName.Contains(Locale.Get("生命"))) { val = FindSprite("Inv_health_backboard_SS"); } else if (displayName.Contains(Locale.Get("念珠"))) { val = FindSprite("coinget_01"); } else if (displayName.Contains(Locale.Get("甲壳"))) { val = FindSprite("Shell_shard_icon"); } else if (displayName.Contains(Locale.Get("蓝血"))) { val = FindSprite("Icon_Inv_Blue_Health_Blood"); } else if (displayName.Contains(Locale.Get("灵丝碎片"))) { val = FindSprite("silk_heart_inv_icon_empty"); } else if (displayName.Contains(Locale.Get("丝轴碎片"))) { val = FindSprite("spool_upgrade_pickup"); } else if (displayName.Contains(Locale.Get("面具碎片"))) { val = FindSprite("mask_first"); } else if (displayName.Contains(Locale.Get("丝线恢复上限"))) { val = FindSprite("prompt_silkheart"); } else if (displayName.Contains(Locale.Get("完全恢复"))) { val = FindSprite("Inv_health_backboard_SS"); } else if (reward.Id == "virt:UnlockCrestSlot") { ToolItemType? lastUnlockedSlotType = ItemRandomizer.LastUnlockedSlotType; if (lastUnlockedSlotType.HasValue) { ToolItemType value2 = lastUnlockedSlotType.Value; string text = ((object)(ToolItemType)(ref value2)).ToString().ToLower(); if (text.Contains("attack")) { val = FindSprite("UI_tool_slot_attack0000"); } else if (text.Contains("defend")) { val = FindSprite("UI_tool_slot_defend0000"); } else if (text.Contains("socket") || text.Contains("tool") || text.Contains("item")) { val = FindSprite("UI_tool_slot_socket0000"); } } if ((Object)(object)val == (Object)null) { string[] array = new string[3] { "UI_tool_slot_attack0000", "UI_tool_slot_defend0000", "UI_tool_slot_socket0000" }; val = FindSprite(array[Random.Range(0, array.Length)]); } if ((Object)(object)val == (Object)null) { val = FindSprite("spool_upgrade_pickup") ?? FindSprite("simple_key_icon") ?? FindSprite("mask_first"); } } _iconCache[reward.Id] = val; return val; } private static Sprite FindSprite(string name) { return ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Sprite s) => ((Object)s).name == name)); } private static Sprite GetDefaultFallbackIcon() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown if ((Object)(object)_defaultFallbackIcon == (Object)null) { Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, Color.white); val.Apply(); _defaultFallbackIcon = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), Vector2.zero); } return _defaultFallbackIcon; } } public interface IRandomReward { string Id { get; } string DisplayName { get; } Sprite Icon { get; } void Give(); bool IsAtMax(); } public class ItemLimitSettings { public int SkillItem = 2; public int Relic = 2; public int OtherItem = 2; public int UpSlash = 1; public int LeftSlash = 1; public int RightSlash = 1; public int DashLeft = 1; public int DashRight = 1; public int HarpoonLeft = 1; public int HarpoonRight = 1; public int FloatLeft = 1; public int FloatRight = 1; public int WallJumpLeft = 1; public int WallJumpRight = 1; public int Heal = 1; public int NeedleThrow = 1; public int ThreadSphere = 1; public int HarpoonDash = 1; public int SilkCharge = 1; public int SilkBomb = 1; public int SilkBossNeedle = 1; public int Needolin = 1; public int Parry = 1; public int NeedolinMemory = 1; public int FastTravel = 1; public int EvaHeal = 1; public int Dash = 1; public int Brolly = 1; public int DoubleJump = 1; public int SuperJump = 1; public int WallJump = 1; public int ChargeSlash = 1; public int HeartPiece = 2; public int SpoolPart = 2; public int MaxSilkRegenUp = 2; public int UnlockCrestSlot = 2; } public class InfinitePoolSettings { public bool Silk = true; public bool FullRestore = true; public bool BlueHealth = true; public bool Geo300 = true; public bool Shards300 = true; public bool SilkParts = true; } public class SavedItemReward : IRandomReward { private SavedItem _item; private static bool _displayNameErrorLogged; private static bool _iconErrorLogged; public string Id { get { SavedItem item = _item; return ((item != null) ? ((Object)item).name : null) ?? "null"; } } public string DisplayName { get { if ((Object)(object)_item == (Object)null) { return Locale.Get("空物品"); } if (_item is ToolCrest) { return ((Object)_item).name; } try { return _item.GetPopupName(); } catch { return ((Object)_item).name; } } } public Sprite Icon { get { if ((Object)(object)_item == (Object)null) { return null; } try { return _item.GetPopupIcon(); } catch { return null; } } } public SavedItem Item => _item; public SavedItemReward(SavedItem item) { _item = item; } public void Give() { SavedItem item = _item; if (item != null) { item.TryGet(false, true); } } public bool IsAtMax() { return ItemRandomizer.GetGivenCount(Id) >= ItemLimitConfig.GetItemTypeLimit(_item); } } public class VirtualReward : IRandomReward { private readonly string _id; private readonly string _displayName; private readonly Sprite _icon; private readonly Action _giveAction; private readonly Func _isAtMax; public string Id => _id; public string DisplayName => _displayName; public Sprite Icon => _icon; public VirtualReward(string id, string displayName, Sprite icon, Action giveAction, Func isAtMax) { _id = id; _displayName = displayName; _icon = icon; _giveAction = giveAction; _isAtMax = isAtMax; } public void Give() { _giveAction?.Invoke(); } public bool IsAtMax() { return _isAtMax?.Invoke() ?? false; } } public class DirectionPermissionReward : IRandomReward { private readonly string _id; private readonly string _displayName; private readonly Sprite _icon; private readonly string _skillField; private readonly bool _allowRight; private readonly bool _allowLeft; private readonly bool _isAttack; private readonly bool _isHeal; public string Id => _id; public string DisplayName => _displayName; public Sprite Icon => _icon; public DirectionPermissionReward(string displayName, string skillField, bool allowRight, bool allowLeft, bool isAttack = false, bool isHeal = false) { _id = "perm:" + skillField + "_" + (allowRight ? "R" : "") + (allowLeft ? "L" : ""); _displayName = displayName; _skillField = skillField; _allowRight = allowRight; _allowLeft = allowLeft; _isAttack = isAttack; _isHeal = isHeal; _icon = null; } public void Give() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown if (_isAttack) { if (_skillField == "upward") { StartingAbilityPickerAPI.SetAttackPermissions(true, false, false); } else if (_skillField == "left") { StartingAbilityPickerAPI.SetAttackPermissions(false, true, false); } else if (_skillField == "right") { StartingAbilityPickerAPI.SetAttackPermissions(false, false, true); } return; } if (_isHeal) { StartingAbilityPickerAPI.SetMovementPermissions(new DirectionPermissions { AllowHeal = true }); return; } DirectionPermissions movementPermissions = StartingAbilityPickerAPI.GetMovementPermissions(); if (_skillField == "hasDash") { movementPermissions.DashLeft = _allowLeft; movementPermissions.DashRight = _allowRight; } else if (_skillField == "hasHarpoonDash") { movementPermissions.HarpoonLeft = _allowLeft; movementPermissions.HarpoonRight = _allowRight; } else if (_skillField == "hasBrolly") { movementPermissions.FloatLeft = _allowLeft; movementPermissions.FloatRight = _allowRight; } else if (_skillField == "hasWalljump") { movementPermissions.WallJumpLeft = _allowLeft; movementPermissions.WallJumpRight = _allowRight; } StartingAbilityPickerAPI.SetMovementPermissions(movementPermissions); } public bool IsAtMax() { return ItemRandomizer.GetGivenCount(Id) >= ItemLimitConfig.GetDirectionLimit(Id); } } public class ProxySavedItem : SavedItem { private IRandomReward _reward; public override bool IsUnique => false; public void Init(IRandomReward reward) { _reward = reward; ((Object)this).name = _reward.Id; } public override string GetPopupName() { return _reward.DisplayName; } public override Sprite GetPopupIcon() { return _reward.Icon; } public override void Get(bool showPopup = true) { _reward.Give(); } public override bool CanGetMore() { return !_reward.IsAtMax(); } public override int GetSavedAmount() { return 0; } } public class LimitedVirtualReward : IRandomReward { private readonly string _id; private readonly string _displayName; private readonly Sprite _icon; private readonly Action _giveAction; private readonly int _maxCount; public string Id => _id; public string DisplayName => _displayName; public Sprite Icon => _icon; public LimitedVirtualReward(string id, string displayName, Sprite icon, Action giveAction, int maxCount) { _id = id; _displayName = displayName; _icon = icon; _giveAction = giveAction; _maxCount = maxCount; } public void Give() { _giveAction?.Invoke(); ItemRandomizer.AddGivenCount(Id); } public bool IsAtMax() { return ItemRandomizer.GetGivenCount(Id) >= _maxCount; } } [HarmonyPatch(typeof(ShopItemStats), "SetPurchased")] public static class ShopItemStats_Purchase_Patch { private static MethodInfo _buildItemListMethod; static ShopItemStats_Purchase_Patch() { _buildItemListMethod = typeof(ShopMenuStock).GetMethod("BuildItemList", BindingFlags.Instance | BindingFlags.NonPublic); } [HarmonyPrefix] private static bool Prefix(ShopItemStats __instance, Action onComplete, int subItemIndex) { if (!SilksongItemRandomizerAPI.IsEnabled()) { return true; } string slotId = ShopSlotHelper.GetSlotId(__instance); if (string.IsNullOrEmpty(slotId)) { return true; } if (ShopMenuStock_BuildItemList_Patch.GetCount(slotId) <= 0) { return false; } ShopMenuStock_BuildItemList_Patch.SetCount(slotId, 0); return true; } [HarmonyPostfix] private static void Postfix(ShopItemStats __instance) { if (!SilksongItemRandomizerAPI.IsEnabled()) { return; } ((Component)__instance).gameObject.SetActive(false); ShopMenuStock componentInParent = ((Component)__instance).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null) { LayoutGroup component = ((Component)componentInParent).GetComponent(); if ((Object)(object)component != (Object)null) { LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)component).GetComponent()); } } } } public static class ShopSlotHelper { private static FieldInfo _spawnedStockField; static ShopSlotHelper() { _spawnedStockField = AccessTools.Field(typeof(ShopMenuStock), "spawnedStock"); } public static string GetSlotId(ShopItemStats stats) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) ShopMenuStock componentInParent = ((Component)stats).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || _spawnedStockField == null) { return null; } if (!(_spawnedStockField.GetValue(componentInParent) is IList list)) { return null; } int num = list.IndexOf(stats); if (num < 0) { return null; } Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; return $"{name}_{num}"; } } [HarmonyPatch(typeof(ShopMenuStock), "BuildItemList")] public static class ShopMenuStock_BuildItemList_Patch { public interface IShopSlotCountAccessor { int GetCount(string permanentId); void SetCount(string permanentId, int count); } [CompilerGenerated] private sealed class d__20 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public float yDistanceRaw; public int visibleCount; public ScrollRect scrollRect; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: { <>1__state = -1; float num = Mathf.Abs(yDistanceRaw); float num2 = (float)visibleCount * num + 40f; RectTransform component = ((Component)scrollRect.content).GetComponent(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(component.sizeDelta.x, num2); LayoutRebuilder.ForceRebuildLayoutImmediate(component); Canvas.ForceUpdateCanvases(); } return false; } } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const string LocalizationSheet = "SilksongItemRandomizer"; private const int TARGET_SLOT_COUNT = 12; private static FieldInfo _availableStockField; private static FieldInfo _spawnedStockField; private static FieldInfo _yDistanceField; private static FieldInfo _displayNameField; private static FieldInfo _descriptionField; private static IShopSlotCountAccessor _slotCountAccessor; public static void Initialize(IShopSlotCountAccessor accessor) { _slotCountAccessor = accessor; } private static void RegisterTranslation(string key, string value) { try { if (typeof(Language).GetField("_currentEntrySheets", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null) is Dictionary> dictionary) { if (!dictionary.TryGetValue("SilksongItemRandomizer", out var value2)) { value2 = (dictionary["SilksongItemRandomizer"] = new Dictionary()); } value2[key] = value; } } catch { } } private static string GetItemDisplayName(SavedItem item) { if ((Object)(object)item == (Object)null) { return "???"; } try { return item.GetPopupName(); } catch { return ((Object)item).name; } } private static string GetItemDescription(SavedItem item) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return ""; } try { CollectableItem val = (CollectableItem)(object)((item is CollectableItem) ? item : null); if (val != null) { return val.GetDescription((ReadSource)3); } CollectableRelic val2 = (CollectableRelic)(object)((item is CollectableRelic) ? item : null); if (val2 != null) { PropertyInfo property = typeof(CollectableRelic).GetProperty("Description", BindingFlags.Instance | BindingFlags.Public); if (property != null) { return property.GetValue(val2)?.ToString() ?? ""; } } ToolItem val3 = (ToolItem)(object)((item is ToolItem) ? item : null); if (val3 != null) { return LocalisedString.op_Implicit(val3.Description); } ToolCrest val4 = (ToolCrest)(object)((item is ToolCrest) ? item : null); if (val4 != null) { return LocalisedString.op_Implicit(val4.Description); } MethodInfo method = ((object)item).GetType().GetMethod("GetDescription", BindingFlags.Instance | BindingFlags.Public); if (method != null && method.DeclaringType != typeof(SavedItem)) { return (string)method.Invoke(item, new object[1] { 3 }); } } catch { } return ""; } private static void EnsureShopItemFields() { if (_displayNameField == null) { Type typeFromHandle = typeof(ShopItem); _displayNameField = typeFromHandle.GetField("displayName", BindingFlags.Instance | BindingFlags.NonPublic); _descriptionField = typeFromHandle.GetField("description", BindingFlags.Instance | BindingFlags.NonPublic); } } private static void EnsureReflectionFields() { if (_spawnedStockField == null) { _availableStockField = AccessTools.Field(typeof(ShopMenuStock), "availableStock"); _spawnedStockField = AccessTools.Field(typeof(ShopMenuStock), "spawnedStock"); _yDistanceField = AccessTools.Field(typeof(ShopMenuStock), "yDistance"); } EnsureShopItemFields(); } public static int GetCount(string permanentId) { if (_slotCountAccessor == null) { return 1; } return _slotCountAccessor.GetCount(permanentId); } public static void SetCount(string permanentId, int count) { if (_slotCountAccessor != null) { _slotCountAccessor.SetCount(permanentId, count); } } public static void ResetAllCounts() { Plugin.Log.LogInfo((object)"商店槽位计数已重置(需要外部调用清空)"); } private static ShopItem CreateShopItem(SavedItem savedItem, int price, string permanentId) { ShopItem val = ShopItem.CreateTemp(((Object)savedItem).name); ((Object)val).name = permanentId; string value = "ShopBought_" + permanentId; FieldInfo field = typeof(ShopItem).GetField("playerDataBoolName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(val, value); } FieldInfo field2 = typeof(ShopItem).GetField("savedItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 == null) { return null; } field2.SetValue(val, savedItem); FieldInfo field3 = typeof(ShopItem).GetField("cost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field3 == null) { return null; } field3.SetValue(val, price); typeof(ShopItem).GetField("costReference", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(val, null); typeof(ShopItem).GetField("currencyType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(val, 0); ClearField(val, "requiredItem"); ClearField(val, "upgradeFromItem"); FieldInfo field4 = typeof(ShopItem).GetField("questsAppearConditions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field4 != null && field4.GetValue(val) == null) { Type elementType = field4.FieldType.GetElementType(); field4.SetValue(val, Array.CreateInstance(elementType ?? typeof(object), 0)); } FieldInfo field5 = typeof(ShopItem).GetField("itemSpriteScale", BindingFlags.Instance | BindingFlags.NonPublic); if (field5 != null) { float num = 1f; switch (((Object)savedItem).name) { case "virt:HeartPiece": case "virt:SpoolPart": case "virt:MaxSilkRegenUp": num = 0.5f; break; } field5.SetValue(val, num); } return val; } private static void ClearField(object obj, string fieldName) { FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field.FieldType.IsClass) { field.SetValue(obj, null); } } [IteratorStateMachine(typeof(d__20))] private static IEnumerator AdjustScrollRectDelayed(ScrollRect scrollRect, float yDistanceRaw, int visibleCount) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__20(0) { scrollRect = scrollRect, yDistanceRaw = yDistanceRaw, visibleCount = visibleCount }; } [HarmonyPostfix] private static void Postfix(ShopMenuStock __instance) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) if (!SilksongItemRandomizerAPI.IsEnabled()) { return; } try { EnsureReflectionFields(); Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; IList list = _spawnedStockField.GetValue(__instance) as IList; IList list2 = _availableStockField.GetValue(__instance) as IList; float num = (float)_yDistanceField.GetValue(__instance); if (list == null || list.Count == 0) { return; } Transform parent = ((Component)list[0]).transform.parent; if ((Object)(object)parent == (Object)null) { Plugin.Log.LogWarning((object)"[商店] 无法找到商品容器,将使用原有槽位数"); } if ((Object)(object)parent != (Object)null) { for (int i = list.Count; i < 12; i++) { GameObject obj = Object.Instantiate(((Component)list[0]).gameObject, parent); obj.SetActive(true); ShopItemStats component = obj.GetComponent(); if ((Object)(object)component != (Object)null) { list.Add(component); list2?.Add(component); component.ItemNumber = i; } } } float num2 = 0f - Mathf.Abs(num); list2?.Clear(); float num3 = 0f; HashSet usedInThisShop = new HashSet(); for (int j = 0; j < list.Count; j++) { ShopItemStats val = list[j]; if ((Object)(object)val == (Object)null) { continue; } string permanentId = $"{name}_{j}"; bool num4 = GetCount(permanentId) <= 0; PlayMakerFSM component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null && component2.FsmName == "Shift_pos") { ((Behaviour)component2).enabled = false; } if (num4) { ((Component)val).gameObject.SetActive(false); continue; } int price; SavedItem orCreateShopItem = ShopRandomizer.GetOrCreateShopItem(permanentId, out price, usedInThisShop); if ((Object)(object)orCreateShopItem == (Object)null) { ((Component)val).gameObject.SetActive(false); continue; } ShopItem val2 = CreateShopItem(orCreateShopItem, price, permanentId); if ((Object)(object)val2 == (Object)null) { ((Component)val).gameObject.SetActive(false); continue; } if (_displayNameField != null) { string itemDisplayName = GetItemDisplayName(orCreateShopItem); string text = "item_" + ((Object)orCreateShopItem).name; RegisterTranslation(text, itemDisplayName); _displayNameField.SetValue(val2, (object)new LocalisedString("SilksongItemRandomizer", text)); } if (_descriptionField != null) { string itemDescription = GetItemDescription(orCreateShopItem); if (!string.IsNullOrEmpty(itemDescription)) { string text2 = "desc_" + ((Object)orCreateShopItem).name; RegisterTranslation(text2, itemDescription); _descriptionField.SetValue(val2, (object)new LocalisedString("SilksongItemRandomizer", text2)); } } val.SetItem(val2); ((Component)val).transform.localPosition = new Vector3(0f, num3, 0f); val.ItemNumber = list2?.Count ?? 0; list2?.Add(val); num3 += num2; ((Component)val).gameObject.SetActive(true); val.UpdateAppearance(); } FieldInfo fieldInfo = AccessTools.Field(typeof(ShopMenuStock), "spawnedSubItems"); if (fieldInfo != null && fieldInfo.GetValue(__instance) is IEnumerable enumerable) { foreach (Component item in enumerable) { Component val3 = item; if ((Object)(object)val3 != (Object)null) { val3.gameObject.SetActive(false); } } } ScrollRect componentInChildren = ((Component)__instance).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.content != (Object)null) { int visibleCount = list2?.Count ?? 0; ((MonoBehaviour)__instance).StartCoroutine(AdjustScrollRectDelayed(componentInChildren, num, visibleCount)); } } catch (Exception arg) { Plugin.Log.LogError((object)$"商店重建补丁异常: {arg}"); } } } public static class ShopRandomizer { public interface IShopSaveDataAccessor { HashSet GetAssignedItemIds(); void SaveAssignedItemIds(HashSet ids); } private class ProxySavedItem : SavedItem { private IRandomReward _reward; public override bool IsUnique => false; public void Init(IRandomReward reward) { _reward = reward; ((Object)this).name = _reward.Id; } public override string GetPopupName() { return _reward.DisplayName; } public override Sprite GetPopupIcon() { return _reward.Icon; } public override void Get(bool showPopup = true) { _reward.Give(); } public override bool CanGetMore() { return !_reward.IsAtMax(); } public override int GetSavedAmount() { return 0; } } [CompilerGenerated] private sealed class d__17 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public int total; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; goto IL_005b; } <>1__state = -1; 5__2 = 0; goto IL_006b; IL_005b: 5__2++; goto IL_006b; IL_006b: if (5__2 < total) { EventRegister.SendEvent(EventRegisterEvents.AddBlueHealth, (GameObject)null); if (5__2 < total - 1) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } goto IL_005b; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static IShopSaveDataAccessor _saveData; private static bool _initialized = false; private static List _allShopItems; private static readonly Dictionary _shopItemCache = new Dictionary(); private static readonly Dictionary _shopPriceCache = new Dictionary(); public static void Initialize(IShopSaveDataAccessor saveDataAccessor) { _saveData = saveDataAccessor; _initialized = true; ResetCache(); } public static void ResetCache() { _shopItemCache.Clear(); _shopPriceCache.Clear(); _allShopItems = null; if (_saveData != null) { _saveData.GetAssignedItemIds().Clear(); } Plugin.Log.LogInfo((object)"商店随机缓存已重置(下次访问时将重新构建物品池)"); } public static void ResetAssignedItems() { if (_saveData != null) { _saveData.GetAssignedItemIds().Clear(); } Plugin.SaveGlobalData(); } private static void MarkItemAsAssigned(string itemId) { if (_saveData != null && _saveData.GetAssignedItemIds().Add(itemId)) { Plugin.SaveGlobalData(); } } private static bool IsItemAssigned(string itemId) { if (_saveData != null) { return _saveData.GetAssignedItemIds().Contains(itemId); } return false; } private static void EnsureAllShopItems() { if (_allShopItems != null) { return; } _allShopItems = new List(); List allItems = ItemRandomizer.GetAllItems(); if (allItems != null) { foreach (SavedItem item in allItems) { if (IsSafeForShop(item)) { _allShopItems.Add(item); } } } List virtualRewardsForShop = GetVirtualRewardsForShop(); foreach (IRandomReward item2 in virtualRewardsForShop) { ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(item2); _allShopItems.Add((SavedItem)(object)proxySavedItem); } Plugin.Log.LogInfo((object)$"商店物品池构建完成:原版 {allItems?.Count ?? 0} 个,虚拟 {virtualRewardsForShop.Count} 个,总计 {_allShopItems.Count} 个"); } private static List GetVirtualRewardsForShop() { return new List { new VirtualReward("virt:Health_2", Locale.Get("小生命"), FindSprite("Inv_health_backboard_SS"), delegate { for (int l = 0; l < 2; l++) { HeroController instance10 = HeroController.instance; if (instance10 != null) { instance10.AddHealth(1); } } }, () => false), new VirtualReward("virt:Silk_3", Locale.Get("中灵丝"), FindSprite("silk_heart_inv_icon"), delegate { for (int k = 0; k < 3; k++) { HeroController instance9 = HeroController.instance; if (instance9 != null) { instance9.AddSilk(1, false); } } }, () => false), new VirtualReward("virt:Geo_100", Locale.Get("小念珠"), FindSprite("coinget_01"), delegate { HeroController instance8 = HeroController.instance; if (instance8 != null) { instance8.AddGeo(100); } }, () => false), new VirtualReward("virt:Geo_300", Locale.Get("大念珠"), FindSprite("coinget_01"), delegate { HeroController instance7 = HeroController.instance; if (instance7 != null) { instance7.AddGeo(300); } }, () => false), new VirtualReward("virt:FullRestore", Locale.Get("完全恢复"), FindSprite("Inv_health_backboard_SS"), delegate { HeroController instance5 = HeroController.instance; PlayerData instance6 = PlayerData.instance; if (!((Object)(object)instance5 == (Object)null) && instance6 != null) { int num = instance6.CurrentMaxHealth - instance6.health; for (int i = 0; i < num; i++) { instance5.AddHealth(1); } int num2 = instance6.CurrentSilkMax - instance6.silk; for (int j = 0; j < num2; j++) { instance5.AddSilk(1, false); } } }, () => false), new LimitedVirtualReward("virt:HeartPiece", Locale.Get("面具碎片"), FindSprite("mask_first"), delegate { PlayerData instance4 = PlayerData.instance; if (instance4 != null) { instance4.heartPieces++; } EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); }, 2), new LimitedVirtualReward("virt:SpoolPart", Locale.Get("丝轴碎片"), FindSprite("spool_upgrade_pickup"), delegate { PlayerData instance2 = PlayerData.instance; if (instance2 != null) { instance2.silkSpoolParts++; } GameCameras instance3 = GameCameras.instance; if (instance3 != null) { SilkSpool silkSpool = instance3.silkSpool; if (silkSpool != null) { silkSpool.RefreshSilk(); } } EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); }, 2), new LimitedVirtualReward("virt:MaxSilkRegenUp", Locale.Get("丝线恢复上限 +1"), FindSprite("prompt_silkheart"), delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddToMaxSilkRegen(1); } }, 2), new LimitedVirtualReward("virt:UnlockCrestSlot", Locale.Get("纹章槽位解锁器"), FindSprite("spool_upgrade_pickup"), delegate { ItemRandomizer.TryUnlockCrestSlot(); }, 20) }; } private static Sprite FindSprite(string name) { return ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((Sprite s) => ((Object)s).name == name)); } private static SavedItem GetRandomCoinItem(string permanentId, out int price) { price = 1; int amount = Random.Range(50, 301); string displayName = string.Format(Locale.Get("随机念珠"), amount); VirtualReward reward = new VirtualReward($"virt:RandomCoin_{amount}", displayName, FindSprite("coinget_01"), delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddGeo(amount); } }, () => false); ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(reward); return (SavedItem)(object)proxySavedItem; } private static SavedItem GetRandomBlueHealthItem(string permanentId, out int price) { price = 1; int total = Random.Range(1, 7); string displayName = string.Format(Locale.Get("随机蓝血"), total); VirtualReward reward = new VirtualReward($"virt:BlueHealth_{total}", displayName, FindSprite("Icon_Inv_Blue_Health_Blood"), delegate { Plugin instance = Plugin.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(GiveBlueHealthOverTime(total)); } }, () => false); ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(reward); return (SavedItem)(object)proxySavedItem; } private static SavedItem GetRandomCapUpgradeItem(string permanentId, out int price) { price = Random.Range(60, 121); List<(string, string, Sprite, Action)> list = new List<(string, string, Sprite, Action)> { ("virt:HeartPiece", Locale.Get("面具碎片"), FindSprite("mask_first"), delegate { PlayerData instance4 = PlayerData.instance; if (instance4 != null) { instance4.heartPieces++; } EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); }), ("virt:SpoolPart", Locale.Get("丝轴碎片"), FindSprite("spool_upgrade_pickup"), delegate { PlayerData instance2 = PlayerData.instance; if (instance2 != null) { instance2.silkSpoolParts++; } GameCameras instance3 = GameCameras.instance; if (instance3 != null) { SilkSpool silkSpool = instance3.silkSpool; if (silkSpool != null) { silkSpool.RefreshSilk(); } } EventRegister.SendEvent(EventRegisterEvents.EquipsChangedEvent, (GameObject)null); }), ("virt:MaxSilkRegenUp", Locale.Get("丝线恢复上限 +1"), FindSprite("prompt_silkheart"), delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddToMaxSilkRegen(1); } }) }; (string, string, Sprite, Action) tuple = list[Random.Range(0, list.Count)]; LimitedVirtualReward reward = new LimitedVirtualReward(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4, 2); ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(reward); return (SavedItem)(object)proxySavedItem; } [IteratorStateMachine(typeof(d__17))] private static IEnumerator GiveBlueHealthOverTime(int total) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__17(0) { total = total }; } public static SavedItem GetOrCreateShopItem(string permanentId, out int price, HashSet usedInThisShop) { EnsureAllShopItems(); int result = -1; string[] array = permanentId.Split(new char[1] { '_' }); int num = array.Length - 1; while (num >= 0 && !int.TryParse(array[num], out result)) { num--; } switch (result) { case 0: { if (_shopItemCache.TryGetValue(permanentId, out var value3)) { price = _shopPriceCache[permanentId]; return value3; } SavedItem randomCoinItem = GetRandomCoinItem(permanentId, out price); _shopItemCache[permanentId] = randomCoinItem; _shopPriceCache[permanentId] = price; return randomCoinItem; } case 1: { if (_shopItemCache.TryGetValue(permanentId, out var value4)) { price = _shopPriceCache[permanentId]; return value4; } SavedItem randomBlueHealthItem = GetRandomBlueHealthItem(permanentId, out price); _shopItemCache[permanentId] = randomBlueHealthItem; _shopPriceCache[permanentId] = price; return randomBlueHealthItem; } case 2: { if (_shopItemCache.TryGetValue(permanentId, out var value2)) { price = _shopPriceCache[permanentId]; return value2; } SavedItem randomCapUpgradeItem = GetRandomCapUpgradeItem(permanentId, out price); _shopItemCache[permanentId] = randomCapUpgradeItem; _shopPriceCache[permanentId] = price; return randomCapUpgradeItem; } default: { if (_shopItemCache.TryGetValue(permanentId, out var value) && !IsItemOwned(value)) { if (!_shopPriceCache.TryGetValue(permanentId, out price)) { Random rng = new Random(Plugin.RandomSeed.Value ^ permanentId.GetHashCode()); price = GenerateRandomPrice(rng); _shopPriceCache[permanentId] = price; } if (usedInThisShop.Contains(((Object)value).name)) { return GenerateRandomShopItem(permanentId, out price, usedInThisShop); } usedInThisShop.Add(((Object)value).name); return value; } SavedItem val = GenerateRandomShopItem(permanentId, out price, usedInThisShop); if ((Object)(object)val == (Object)null) { price = 10; VirtualReward reward = new VirtualReward("virt:FallbackGeo", Locale.Get("保底念珠"), FindSprite("coinget_01"), delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddGeo(10); } }, () => false); ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(reward); val = (SavedItem)(object)proxySavedItem; } _shopItemCache[permanentId] = val; _shopPriceCache[permanentId] = price; usedInThisShop.Add(((Object)val).name); return val; } } } private static SavedItem GenerateRandomShopItem(string permanentId, out int price, HashSet usedInThisShop) { Random random = new Random(Plugin.RandomSeed.Value ^ permanentId.GetHashCode()); EnsureAllShopItems(); if (_allShopItems.Count == 0) { price = 0; return null; } List list = _allShopItems.Where((SavedItem item) => !IsItemOwned(item) && IsSafeForShop(item) && !IsItemAssigned(((Object)item).name) && !usedInThisShop.Contains(((Object)item).name)).ToList(); if (list.Count == 0) { Plugin.Log.LogWarning((object)("商店随机池已无可用物品,使用保底念珠 (永久ID: " + permanentId + ")")); price = 10; VirtualReward reward = new VirtualReward("virt:FallbackGeo", Locale.Get("保底念珠"), FindSprite("coinget_01"), delegate { HeroController instance = HeroController.instance; if (instance != null) { instance.AddGeo(10); } }, () => false); ProxySavedItem proxySavedItem = new ProxySavedItem(); proxySavedItem.Init(reward); return (SavedItem)(object)proxySavedItem; } SavedItem obj = list[random.Next(list.Count)]; price = GenerateRandomPrice(random); MarkItemAsAssigned(((Object)obj).name); return obj; } private static bool IsItemOwned(SavedItem item) { try { return !item.CanGetMore(); } catch { return false; } } private static bool IsSafeForShop(SavedItem item) { if ((Object)(object)item == (Object)null) { return false; } if (ItemRandomizer.ExcludedNames.Contains(((Object)item).name)) { return false; } if (item is ToolCrest) { return false; } MethodInfo method = ((object)item).GetType().GetMethod("GetPopupIcon", BindingFlags.Instance | BindingFlags.Public); if (method == null || method.DeclaringType == typeof(SavedItem)) { return false; } try { if ((Object)(object)item.GetPopupIcon() == (Object)null) { return false; } } catch { return false; } return true; } private static int GenerateRandomPrice(Random rng) { if (rng.Next(2) != 0) { return rng.Next(100, 301); } return rng.Next(1, 100); } } [HarmonyPatch(typeof(PlayerData))] public static class SilkRandomizerPatch { private static Random _rng; private static readonly int[] CostWeights = new int[9] { 1, 1, 1, 1, 2, 2, 2, 2, 2 }; private static void EnsureRng() { if (_rng == null) { _rng = new Random(SilksongItemRandomizerAPI.GetSeed() ^ 0x5A5A5A5A); } } private static int GetRandomGainAmount() { if (_rng.NextDouble() < 0.9) { return 1; } return _rng.Next(2, 10); } private static int GetRandomCostAmount() { int num = 0; int[] costWeights = CostWeights; foreach (int num2 in costWeights) { num += num2; } int num3 = _rng.Next(num); int num4 = 0; for (int j = 0; j < CostWeights.Length; j++) { num4 += CostWeights[j]; if (num3 < num4) { return j + 1; } } return 5; } [HarmonyPatch("AddSilk")] [HarmonyPrefix] private static bool PrefixAddSilk(PlayerData __instance, ref int amount) { if (!SilksongItemRandomizerAPI.IsEnabled()) { return true; } EnsureRng(); amount = GetRandomGainAmount(); return true; } [HarmonyPatch("TakeSilk")] [HarmonyPrefix] private static bool PrefixTakeSilk(PlayerData __instance, ref int amount) { if (!SilksongItemRandomizerAPI.IsEnabled()) { return true; } EnsureRng(); amount = GetRandomCostAmount(); return true; } } public class ItemRandomizerConfig { public int Seed; public bool Enabled; public bool CrestEnabled; public bool TrapEnabled; public bool TrapMovementEnabled = true; public int TrapDifficulty; public bool CrestRandomEnabled = true; public bool SkillItemRandomEnabled = true; public bool RelicRandomEnabled = true; public int CurrencyFirstThreshold = 30; public int CurrencySecondThreshold = 1000; public int SilkSpearPityCount = 10; public float VirtualUnlimitedProbability = 0.1f; public float CrestUnlockerProbability = 0.1f; public float NormalLimitedProbability = 0.8f; public int MaxGivenPerItem = 2; public ItemLimitSettings Limits = new ItemLimitSettings(); public InfinitePoolSettings InfinitePool = new InfinitePoolSettings(); } public static class SilksongItemRandomizerAPI { public class PluginSaveDataAccessor : ISaveDataAccessor, ShopRandomizer.IShopSaveDataAccessor, CurrencyCollectPatch.ICurrencySaveDataAccessor, SilkSpearPityPatch.ISilkSpearSaveDataAccessor, ICrestSaveDataAccessor, PickupPatch.IPickupSaveDataAccessor, Extracurrencypickup.IExtraPickupSaveDataAccessor, BenchRespawnPatch.IBenchRespawnSaveDataAccessor, CrestRandomizePatch.ICrestPatchSaveDataAccessor, ToolEffectRandomizer.IToolEffectSaveDataAccessor, ShopMenuStock_BuildItemList_Patch.IShopSlotCountAccessor { public Dictionary GetItemGivenCounts() { return Plugin.SaveData.ItemGivenCounts; } public void SaveItemGivenCounts(Dictionary counts) { Plugin.SaveData.ItemGivenCounts = counts; Plugin.SaveGlobalData(); } public Dictionary GetTotalMappings() { return Plugin.SaveData.TotalMappings; } public void SaveTotalMappings(Dictionary mappings) { Plugin.SaveData.TotalMappings = mappings; Plugin.SaveGlobalData(); } public HashSet GetAssignedItemIds() { return Plugin.SaveData.ShopAssignedItemIds; } public void SaveAssignedItemIds(HashSet ids) { Plugin.SaveData.ShopAssignedItemIds = ids; Plugin.SaveGlobalData(); } public int GetTotalCollectCount() { return Plugin.SaveData.CurrencyTotalCollectCount; } public void SetTotalCollectCount(int count) { Plugin.SaveData.CurrencyTotalCollectCount = count; Plugin.SaveGlobalData(); } public bool GetFirstKeyGiven() { return Plugin.SaveData.CurrencyFirstKeyGiven; } public void SetFirstKeyGiven(bool given) { Plugin.SaveData.CurrencyFirstKeyGiven = given; Plugin.SaveGlobalData(); } public bool GetSecondKeyGiven() { return Plugin.SaveData.CurrencySecondKeyGiven; } public void SetSecondKeyGiven(bool given) { Plugin.SaveData.CurrencySecondKeyGiven = given; Plugin.SaveGlobalData(); } public int GetFirstThreshold() { return Plugin.SaveData.CurrencyFirstThreshold; } public void SetFirstThreshold(int threshold) { Plugin.SaveData.CurrencyFirstThreshold = threshold; Plugin.SaveGlobalData(); } public int GetSecondThreshold() { return Plugin.SaveData.CurrencySecondThreshold; } public void SetSecondThreshold(int threshold) { Plugin.SaveData.CurrencySecondThreshold = threshold; Plugin.SaveGlobalData(); } public int GetTryGetCount() { return Plugin.SaveData.SilkSpearTryGetCount; } public void SetTryGetCount(int count) { Plugin.SaveData.SilkSpearTryGetCount = count; Plugin.SaveGlobalData(); } public bool GetSilkSpearGiven() { return Plugin.SaveData.SilkSpearGiven; } public void SetSilkSpearGiven(bool given) { Plugin.SaveData.SilkSpearGiven = given; Plugin.SaveGlobalData(); } public int GetPityCount() { return Plugin.SaveData.SilkSpearPityCount; } public void SetPityCount(int count) { Plugin.SaveData.SilkSpearPityCount = count; Plugin.SaveGlobalData(); } public Dictionary GetCrestMappings() { return Plugin.SaveData.CrestMappings; } public void SaveCrestMappings(Dictionary mappings) { Plugin.SaveData.CrestMappings = mappings; Plugin.SaveGlobalData(); } public HashSet GetUnlockedCrests() { return Plugin.SaveData.UnlockedCrests; } public void SaveUnlockedCrests(HashSet unlockedCrests) { Plugin.SaveData.UnlockedCrests = unlockedCrests; Plugin.SaveGlobalData(); } public string GetLastUnlockedCrest() { return Plugin.SaveData.LastUnlockedCrest; } public void SetLastUnlockedCrest(string crestName) { Plugin.SaveData.LastUnlockedCrest = crestName; Plugin.SaveGlobalData(); } public HashSet GetPickedPickupKeys() { return Plugin.SaveData.PickedPickupKeys; } public void SavePickedPickupKeys(HashSet keys) { Plugin.SaveData.PickedPickupKeys = keys; Plugin.SaveGlobalData(); } public HashSet GetPickedPositions() { return Plugin.SaveData.PickedPositions; } public void SavePickedPositions(HashSet positions) { Plugin.SaveData.PickedPositions = positions; Plugin.SaveGlobalData(); } public string GetLastUnlockedCrestForRespawn() { return Plugin.SaveData.LastUnlockedCrest; } public HashSet GetDisabledChapels() { return Plugin.SaveData.DisabledChapels; } public void SaveDisabledChapels(HashSet disabledChapels) { Plugin.SaveData.DisabledChapels = disabledChapels; Plugin.SaveGlobalData(); } public Dictionary> GetCrestEffects() { return Plugin.SaveData.CrestEffects; } public void SaveCrestEffects(Dictionary> effects) { Plugin.SaveData.CrestEffects = effects; Plugin.SaveGlobalData(); } public int GetCount(string permanentId) { if (!Plugin.SaveData.ShopSlotCounts.TryGetValue(permanentId, out var value)) { return 1; } return value; } public void SetCount(string permanentId, int count) { Plugin.SaveData.ShopSlotCounts[permanentId] = count; Plugin.SaveGlobalData(); } } public class CrestSaveDataAccessor : ICrestSaveDataAccessor { public Dictionary GetCrestMappings() { return Plugin.SaveData.CrestMappings; } public void SaveCrestMappings(Dictionary mappings) { Plugin.SaveData.CrestMappings = mappings; Plugin.SaveGlobalData(); } public HashSet GetUnlockedCrests() { return Plugin.SaveData.UnlockedCrests; } public void SaveUnlockedCrests(HashSet unlockedCrests) { Plugin.SaveData.UnlockedCrests = unlockedCrests; Plugin.SaveGlobalData(); } public string GetLastUnlockedCrest() { return Plugin.SaveData.LastUnlockedCrest; } public void SetLastUnlockedCrest(string crestName) { Plugin.SaveData.LastUnlockedCrest = crestName; Plugin.SaveGlobalData(); } } private static ItemRandomizerConfig _cachedConfig; private static bool _pendingChanges = false; private static bool _isGameReady = false; private static bool _initialized = false; private static bool _harmonyPatched = false; private static Harmony _harmony; private static readonly string HarmonyId = "SilksongItemRandomizer.Core"; public static void Initialize(ItemRandomizerConfig config) { if (!_initialized) { _cachedConfig = config ?? new ItemRandomizerConfig(); _initialized = true; _pendingChanges = true; SyncToInternalFields(); } } public static void MarkGameReady() { if (!_isGameReady) { _isGameReady = true; if (_pendingChanges) { ApplyPending(); } } } public static void SetEnabled(bool enabled) { _cachedConfig.Enabled = enabled; MarkPendingAndApply(); } public static void SetCrestEnabled(bool enabled) { _cachedConfig.CrestEnabled = enabled; MarkPendingAndApply(); } public static void SetTrapEnabled(bool enabled) { _cachedConfig.TrapEnabled = enabled; MarkPendingAndApply(); } public static void SetTrapMovementEnabled(bool enabled) { _cachedConfig.TrapMovementEnabled = enabled; MarkPendingAndApply(); } public static void SetTrapDifficulty(int difficulty) { _cachedConfig.TrapDifficulty = difficulty; MarkPendingAndApply(); } public static void SetSeed(int seed) { _cachedConfig.Seed = seed; MarkPendingAndApply(); } public static void SetCrestRandomEnabled(bool enabled) { _cachedConfig.CrestRandomEnabled = enabled; MarkPendingAndApply(); } public static void SetSkillItemRandomEnabled(bool enabled) { _cachedConfig.SkillItemRandomEnabled = enabled; MarkPendingAndApply(); } public static void SetRelicRandomEnabled(bool enabled) { _cachedConfig.RelicRandomEnabled = enabled; MarkPendingAndApply(); } public static void SetCurrencyThresholds(int first, int second) { _cachedConfig.CurrencyFirstThreshold = first; _cachedConfig.CurrencySecondThreshold = second; MarkPendingAndApply(); } public static void SetSilkSpearPityCount(int count) { _cachedConfig.SilkSpearPityCount = count; MarkPendingAndApply(); } public static void SetItemLimits(ItemLimitSettings limits) { _cachedConfig.Limits = limits; MarkPendingAndApply(); } public static void SetInfinitePoolSettings(InfinitePoolSettings settings) { _cachedConfig.InfinitePool = settings; MarkPendingAndApply(); } public static void SetVirtualProbabilities(float virtualProb, float crestProb, float normalProb) { _cachedConfig.VirtualUnlimitedProbability = virtualProb; _cachedConfig.CrestUnlockerProbability = crestProb; _cachedConfig.NormalLimitedProbability = normalProb; MarkPendingAndApply(); } public static void ApplyNow() { if (_isGameReady || _initialized) { ApplyPending(); } } public static bool IsEnabled() { return _cachedConfig.Enabled; } public static bool IsCrestEnabled() { return _cachedConfig.CrestEnabled; } public static bool IsTrapEnabled() { return _cachedConfig.TrapEnabled; } public static bool IsTrapMovementEnabled() { return _cachedConfig.TrapMovementEnabled; } public static int GetTrapDifficulty() { return _cachedConfig.TrapDifficulty; } public static int GetSeed() { return _cachedConfig.Seed; } public static bool IsCrestRandomEnabled() { return _cachedConfig.CrestRandomEnabled; } public static bool IsSkillItemRandomEnabled() { return _cachedConfig.SkillItemRandomEnabled; } public static bool IsRelicRandomEnabled() { return _cachedConfig.RelicRandomEnabled; } public static (int first, int second) GetCurrencyThresholds() { return (_cachedConfig.CurrencyFirstThreshold, _cachedConfig.CurrencySecondThreshold); } public static int GetSilkSpearPityCount() { return _cachedConfig.SilkSpearPityCount; } public static void RegenerateTrapsNow() { if (_isGameReady && _cachedConfig.TrapEnabled) { TrapRandomizer.RespawnTraps(); } } public static void ResetAllData() { Plugin.ResetSaveData(); ItemRandomizer.Initialize(_cachedConfig.Seed, _cachedConfig, new PluginSaveDataAccessor(), GetFullRandomMode()); CrestRandomizer.Initialize(_cachedConfig.Seed, _cachedConfig.CrestEnabled, new CrestSaveDataAccessor()); CrestRandomizePatch.ResetProcessedIds(); CurrencyCollectPatch.ResetCounters(); SilkSpearPityPatch.ResetSilkSpearState(); PickupPatch.ResetAll(); ShopRandomizer.ResetCache(); Extracurrencypickup.ResetAll(); ShopMenuStock_BuildItemList_Patch.ResetAllCounts(); TrapRandomizer.ClearAll(); BenchRespawnPatch.ResetCooldown(); } private static void MarkPendingAndApply() { _pendingChanges = true; ApplyPending(); } private static void ApplyPending() { if (_isGameReady || _pendingChanges) { SyncToInternalFields(); ItemLimitConfig.Apply(_cachedConfig.Limits); ItemLimitConfig.ApplyInfinitePoolSettings(_cachedConfig.InfinitePool); ItemTypeRandomFilter.Apply(_cachedConfig.CrestRandomEnabled, _cachedConfig.SkillItemRandomEnabled, _cachedConfig.RelicRandomEnabled); GlobalSaveData saveData = Plugin.SaveData; saveData.CurrencyFirstThreshold = _cachedConfig.CurrencyFirstThreshold; saveData.CurrencySecondThreshold = _cachedConfig.CurrencySecondThreshold; saveData.SilkSpearPityCount = _cachedConfig.SilkSpearPityCount; saveData.VirtualUnlimitedProbability = _cachedConfig.VirtualUnlimitedProbability; saveData.CrestUnlockerProbability = _cachedConfig.CrestUnlockerProbability; saveData.NormalLimitedProbability = _cachedConfig.NormalLimitedProbability; saveData.MaxGivenPerItem = _cachedConfig.MaxGivenPerItem; saveData.TrapEnabled = _cachedConfig.TrapEnabled; saveData.TrapMovementEnabled = _cachedConfig.TrapMovementEnabled; GlobalSaveData globalSaveData = saveData; globalSaveData.TrapDifficulty = _cachedConfig.TrapDifficulty switch { 0 => "Beginner", 1 => "Focused", 2 => "Overflow", _ => "Beginner", }; Plugin.SaveGlobalData(); bool fullRandomMode = GetFullRandomMode(); ItemRandomizer.Initialize(_cachedConfig.Seed, _cachedConfig, new PluginSaveDataAccessor(), fullRandomMode); CrestRandomizer.Initialize(_cachedConfig.Seed, _cachedConfig.CrestEnabled, new CrestSaveDataAccessor()); if (_cachedConfig.TrapEnabled) { TrapRandomizer.Initialize(new TrapRandomConfig { Seed = _cachedConfig.Seed, Enabled = _cachedConfig.TrapEnabled, MovementEnabled = _cachedConfig.TrapMovementEnabled, Difficulty = _cachedConfig.TrapDifficulty, FrostBannedScenes = Plugin.SaveData.TrapFrostBannedScenes }); } else { TrapRandomizer.ClearAll(); } ToolEffectRandomizer.SetEnabled(_cachedConfig.CrestEnabled); ShopRandomizer.ResetCache(); if (_cachedConfig.Enabled && !_harmonyPatched) { ApplyHarmonyPatches(); _harmonyPatched = true; PickupPatch.EnableRandomizer(); } else if (!_cachedConfig.Enabled && _harmonyPatched) { RemoveHarmonyPatches(); _harmonyPatched = false; PickupPatch.DisableRandomizer(); } _pendingChanges = false; } } private static void SyncToInternalFields() { if (Plugin.RandomSeed != null) { Plugin.RandomSeed.Value = _cachedConfig.Seed; } if (Plugin.ItemRandomEnabled != null) { Plugin.ItemRandomEnabled.Value = _cachedConfig.Enabled; } if (Plugin.CrestRandomEnabled != null) { Plugin.CrestRandomEnabled.Value = _cachedConfig.CrestRandomEnabled; } } private static void ApplyHarmonyPatches() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (_harmony == null) { _harmony = new Harmony(HarmonyId); } _harmony.PatchAll(typeof(PickupPatch)); _harmony.PatchAll(typeof(CurrencyCollectPatch)); _harmony.PatchAll(typeof(TryGetPatch)); _harmony.PatchAll(typeof(CrestRandomizePatch)); _harmony.PatchAll(typeof(ShopMenuStock_BuildItemList_Patch)); _harmony.PatchAll(typeof(ShopItemStats_Purchase_Patch)); _harmony.PatchAll(typeof(SilkSpearPityPatch)); _harmony.PatchAll(typeof(BenchRespawnPatch)); _harmony.PatchAll(typeof(SilkRandomizerPatch)); _harmony.PatchAll(typeof(Extracurrencypickup)); try { EnemyRandoAdjuster.TryPatch(_harmony); } catch { } } private static void RemoveHarmonyPatches() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; } private static bool GetFullRandomMode() { try { Type type = Type.GetType("StartingAbilityPicker.DirectionPatch, StartingAbilityPicker"); if (type == null) { return false; } PropertyInfo property = type.GetProperty("FullRandomMode", BindingFlags.Static | BindingFlags.Public); if (property != null) { object value = property.GetValue(null); if (value is bool) { return (bool)value; } } } catch { } return false; } } [HarmonyPatch(typeof(SavedItem), "TryGet")] public static class SilkSpearPityPatch { public interface ISilkSpearSaveDataAccessor { int GetTryGetCount(); void SetTryGetCount(int count); bool GetSilkSpearGiven(); void SetSilkSpearGiven(bool given); int GetPityCount(); void SetPityCount(int count); } [CompilerGenerated] private sealed class <>c__DisplayClass9_0 { public bool finished; internal void b__0() { finished = true; } } [CompilerGenerated] private sealed class d__10 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; ForceFullHealAndSilk(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__9 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public SkillGetMsg prefab; public ToolItemSkill skillItem; public SavedItem silkSpearItem; private <>c__DisplayClass9_0 <>8__1; private float 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__9(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>8__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass9_0(); <>8__1.finished = false; SkillGetMsg.Spawn(prefab, skillItem, (Action)delegate { <>8__1.finished = true; }); TryGetPatch.BypassRandom = true; try { silkSpearItem.TryGet(false, true); } finally { TryGetPatch.BypassRandom = false; } Plugin.Log.LogInfo((object)"[丝矛保底] 原生弹窗已触发,丝矛已给予"); 5__2 = 15f; goto IL_00bd; case 1: <>1__state = -1; 5__2 -= Time.deltaTime; goto IL_00bd; case 2: { <>1__state = -1; ForceFullHealAndSilk(); return false; } IL_00bd: if (!<>8__1.finished && 5__2 > 0f) { <>2__current = null; <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(5f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static ISilkSpearSaveDataAccessor _saveData; private static SkillGetMsg _cachedSkillMsgPrefab; private static readonly string SKILL_MSG_BUNDLE_NAME = "c3ef29e95eda5580682bb076589a723c.bundle"; private static readonly string SKILL_MSG_ASSET_PATH = "Assets/Prefabs/UI/Hornet UI/Silk_Skill_Get_Prompt.prefab"; public static void Initialize(ISilkSpearSaveDataAccessor saveDataAccessor) { _saveData = saveDataAccessor; if (_saveData != null) { Plugin.Log.LogInfo((object)$"[丝矛保底] 加载状态: 已给予={_saveData.GetSilkSpearGiven()}, 当前计数={_saveData.GetTryGetCount()}"); } } public static void ResetSilkSpearState() { if (_saveData != null) { _saveData.SetTryGetCount(0); _saveData.SetSilkSpearGiven(given: false); Plugin.Log.LogInfo((object)"[丝矛保底] 保底状态已重置"); } } [HarmonyPostfix] private static void Postfix(SavedItem __instance, bool __result) { if (__result && _saveData != null && !_saveData.GetSilkSpearGiven() && !(((Object)__instance).name == "Silk Spear")) { int num = _saveData.GetTryGetCount() + 1; _saveData.SetTryGetCount(num); int pityCount = _saveData.GetPityCount(); Plugin.Log.LogInfo((object)$"[丝矛保底] 物品获得计数: {num}/{pityCount} (物品: {((Object)__instance).name})"); if (num >= pityCount) { Plugin.Log.LogInfo((object)$"[丝矛保底] 保底触发(第{num}次物品获得)"); GiveSilkSpearWithNativePopup(); _saveData.SetSilkSpearGiven(given: true); } } } private static void GiveSilkSpearWithNativePopup() { try { SavedItem val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((SavedItem i) => ((Object)i).name == "Silk Spear")); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"[丝矛保底] 找不到 Silk Spear 物品"); return; } ToolItemSkill val2 = (ToolItemSkill)(object)((val is ToolItemSkill) ? val : null); if (val2 != null) { EnsureCrestSlots(); SkillGetMsg skillMsgPrefab = GetSkillMsgPrefab(); if ((Object)(object)skillMsgPrefab != (Object)null) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(ShowNativePopupAndRefreshHealth(skillMsgPrefab, val2, val)); return; } } TryGetPatch.BypassRandom = true; try { val.TryGet(false, true); } finally { TryGetPatch.BypassRandom = false; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedHealAndSilk()); Plugin.Log.LogInfo((object)"[丝矛保底] 降级给予丝矛,5秒后回满血丝"); } catch (Exception arg) { Plugin.Log.LogError((object)$"[丝矛保底] 给予丝矛失败: {arg}"); } } [IteratorStateMachine(typeof(d__9))] private static IEnumerator ShowNativePopupAndRefreshHealth(SkillGetMsg prefab, ToolItemSkill skillItem, SavedItem silkSpearItem) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__9(0) { prefab = prefab, skillItem = skillItem, silkSpearItem = silkSpearItem }; } [IteratorStateMachine(typeof(d__10))] private static IEnumerator DelayedHealAndSilk() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__10(0); } private static void ForceFullHealAndSilk() { try { HeroController instance = HeroController.instance; PlayerData instance2 = PlayerData.instance; if ((Object)(object)instance == (Object)null || instance2 == null) { Plugin.Log.LogWarning((object)"[丝矛保底] HeroController 或 PlayerData 为空,无法回满"); return; } int num = instance2.CurrentMaxHealth - instance2.health; if (num > 0) { for (int i = 0; i < num; i++) { instance.AddHealth(1); } Plugin.Log.LogInfo((object)$"[丝矛保底] 已回满血量 (+{num})"); } int num2 = instance2.CurrentSilkMax - instance2.silk; if (num2 > 0) { for (int j = 0; j < num2; j++) { instance.AddSilk(1, false); } Plugin.Log.LogInfo((object)$"[丝矛保底] 已回满丝线 (+{num2})"); } if (num > 0 || num2 > 0) { return; } EventRegister.SendEvent(EventRegisterEvents.HealthUpdate, (GameObject)null); GameCameras instance3 = GameCameras.instance; if (instance3 != null) { SilkSpool silkSpool = instance3.silkSpool; if (silkSpool != null) { silkSpool.RefreshSilk(); } } Plugin.Log.LogInfo((object)"[丝矛保底] 血量/丝线已满,仅刷新UI"); } catch (Exception arg) { Plugin.Log.LogError((object)$"[丝矛保底] ForceFullHealAndSilk 异常: {arg}"); } } private static void EnsureCrestSlots() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) try { PlayerData instance = PlayerData.instance; if (instance == null) { return; } string crestId = instance.CurrentCrestID; if (string.IsNullOrEmpty(crestId)) { crestId = "Hunter"; } ToolCrest val = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)((ToolCrest c) => c.name == crestId)); if ((Object)(object)val == (Object)null) { return; } Data saveData = val.SaveData; if (saveData.Slots == null || saveData.Slots.Count == 0) { saveData.Slots = new List(); for (int i = 0; i < val.Slots.Length; i++) { saveData.Slots.Add(new SlotData { IsUnlocked = true }); } val.SaveData = saveData; } } catch { } } private static SkillGetMsg GetSkillMsgPrefab() { if ((Object)(object)_cachedSkillMsgPrefab != (Object)null) { return _cachedSkillMsgPrefab; } try { AssetBundle val = null; foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { if ((Object)(object)allLoadedAssetBundle != (Object)null && ((Object)allLoadedAssetBundle).name == SKILL_MSG_BUNDLE_NAME) { val = allLoadedAssetBundle; break; } } if ((Object)(object)val == (Object)null) { string text = Path.Combine(Application.streamingAssetsPath, "aa", "StandaloneWindows64", SKILL_MSG_BUNDLE_NAME); if (File.Exists(text)) { val = AssetBundle.LoadFromFile(text); } } if ((Object)(object)val != (Object)null) { GameObject val2 = val.LoadAsset(SKILL_MSG_ASSET_PATH); if ((Object)(object)val2 != (Object)null) { _cachedSkillMsgPrefab = val2.GetComponent(); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"[丝矛保底] 加载预制体失败: {arg}"); } if ((Object)(object)_cachedSkillMsgPrefab == (Object)null) { Plugin.Log.LogWarning((object)"[丝矛保底] 未找到 SkillGetMsg 预制体,原生弹窗不可用"); } return _cachedSkillMsgPrefab; } } public static class ToolEffectRandomizer { public interface IToolEffectSaveDataAccessor { Dictionary> GetCrestEffects(); void SaveCrestEffects(Dictionary> effects); } private static IToolEffectSaveDataAccessor _saveData; private static bool _initialized = false; private static bool _enabled = false; private static Random _rng; private static int _seed; private static Dictionary _originalHeroValues = new Dictionary(); private static Dictionary _heroFieldCache; private static readonly List HeroFields = new List { "attack_cooldown", "throwToolCooldown", "NAIL_CHARGE_TIME", "NAIL_CHARGE_TIME_QUICK", "RUN_SPEED", "WALK_SPEED", "DASH_SPEED", "DASH_TIME", "AIR_DASH_TIME", "MAX_FALL_VELOCITY" }; private static readonly Dictionary FieldRanges = new Dictionary { ["attack_cooldown"] = (0.25f, 1.2f, 2f), ["throwToolCooldown"] = (0.25f, 1.2f, 2f), ["NAIL_CHARGE_TIME"] = (0.25f, 1.2f, 2f), ["NAIL_CHARGE_TIME_QUICK"] = (0.25f, 1.2f, 2f), ["RUN_SPEED"] = (1.5f, 0.7f, 0.9f), ["WALK_SPEED"] = (1.5f, 0.7f, 0.9f), ["DASH_SPEED"] = (1.5f, 0.7f, 0.9f), ["DASH_TIME"] = (1.5f, 0.7f, 0.9f), ["AIR_DASH_TIME"] = (1.5f, 0.7f, 0.9f), ["MAX_FALL_VELOCITY"] = (1.5f, 0.7f, 0.9f) }; public static void Initialize(IToolEffectSaveDataAccessor saveDataAccessor, int seed) { if (_initialized) { return; } _saveData = saveDataAccessor; _seed = seed; _rng = new Random(_seed ^ 0x7E57C0E); _heroFieldCache = new Dictionary(); Type typeFromHandle = typeof(HeroController); foreach (string heroField in HeroFields) { FieldInfo field = typeFromHandle.GetField(heroField, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { _heroFieldCache[heroField] = field; } } _initialized = true; } public static void SetEnabled(bool enabled) { if (_enabled != enabled) { _enabled = enabled; if (!_enabled) { RemoveCrestEffects(); ResetHeroToOriginal(); } else { ApplyCurrentCrest(); } Plugin.Log.LogInfo((object)("纹章诅咒效果: " + (_enabled ? "启用" : "禁用"))); } } private static void EnsureAllCrestMultipliers() { Dictionary> crestEffects = _saveData.GetCrestEffects(); if (crestEffects.Count > 0) { return; } List list = (from c in Resources.FindObjectsOfTypeAll() where (Object)(object)c != (Object)null && !string.IsNullOrEmpty(c.name) select c.name).Distinct().ToList(); if (list.Count == 0) { return; } foreach (string item in list) { if (crestEffects.ContainsKey(item)) { continue; } List list2 = HeroFields.OrderBy((string x) => _rng.Next()).ToList().Take(3) .ToList(); Dictionary dictionary = new Dictionary(); foreach (string heroField in HeroFields) { (float, float, float) tuple = FieldRanges[heroField]; double num = _rng.NextDouble(); float value = (float)((double)tuple.Item2 + num * (double)(tuple.Item3 - tuple.Item2)); dictionary[heroField] = value; } foreach (string item2 in list2) { if (FieldRanges.TryGetValue(item2, out (float, float, float) value2)) { (dictionary[item2], _, _) = value2; } } crestEffects[item] = dictionary; } _saveData.SaveCrestEffects(crestEffects); } private static void SaveOriginalHeroValues() { if (_originalHeroValues.Count > 0) { return; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return; } foreach (KeyValuePair item in _heroFieldCache) { try { float value = (float)item.Value.GetValue(instance); _originalHeroValues[item.Key] = value; } catch { } } } private static void ResetHeroToOriginal() { if (_originalHeroValues.Count == 0) { return; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return; } foreach (KeyValuePair originalHeroValue in _originalHeroValues) { if (_heroFieldCache.TryGetValue(originalHeroValue.Key, out var value)) { value.SetValue(instance, originalHeroValue.Value); } } } public static void ApplyCrestEffects(string crestId) { if (!_enabled || !_initialized || !SilksongItemRandomizerAPI.IsEnabled() || string.IsNullOrEmpty(crestId)) { return; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return; } SaveOriginalHeroValues(); EnsureAllCrestMultipliers(); if (!_saveData.GetCrestEffects().TryGetValue(crestId, out var value)) { return; } foreach (KeyValuePair item in _heroFieldCache) { string key = item.Key; FieldInfo value2 = item.Value; if (_originalHeroValues.TryGetValue(key, out var value3) && value.TryGetValue(key, out var value4)) { float num = value3 * value4; if (key.Contains("Cooldown") || key.Contains("Time")) { num = Mathf.Max(0.05f, num); } if (key.Contains("SPEED")) { num = Mathf.Max(0.3f, num); } value2.SetValue(instance, num); } } } public static void RemoveCrestEffects() { if (_originalHeroValues.Count == 0) { return; } HeroController instance = HeroController.instance; if ((Object)(object)instance == (Object)null) { return; } foreach (KeyValuePair originalHeroValue in _originalHeroValues) { if (_heroFieldCache.TryGetValue(originalHeroValue.Key, out var value)) { value.SetValue(instance, originalHeroValue.Value); } } } public static void ApplyCurrentCrest() { if (_enabled) { PlayerData instance = PlayerData.instance; if (instance != null && !string.IsNullOrEmpty(instance.CurrentCrestID)) { ApplyCrestEffects(instance.CurrentCrestID); } } } public static void ResetAllEffects() { _saveData.GetCrestEffects().Clear(); _saveData.SaveCrestEffects(new Dictionary>()); _originalHeroValues.Clear(); EnsureAllCrestMultipliers(); ApplyCurrentCrest(); } } public enum TrapPersonality { Friendly, Playful, Sinister } public enum MoveStyle { SurfacePatrol, ZigzagLoop, NeedleSwing, Spin, Pulse, Flicker, Jitter, Bounce } public class TrapMover : MonoBehaviour { public MoveStyle style; public TrapPersonality personality; public float baseSpeed = 1f; private float _currentSpeed; private int _cycleCount; private Vector2 _startPos; private Vector2 _leftEdge; private Vector2 _rightEdge; private int _moveDir = 1; private List _path; private int _pathIndex; private float _pathProgress; private float _swingTimer; private float _startAngle; private float _spinAngle; private int _spinDir = 1; private Vector3 _originalScale; private float _pulseTimer; private SpriteRenderer _spriteRenderer; private float _flickerTimer; private bool _isVisible = true; private Vector3 _originalPos; private float _jitterTimer; private float _bounceTimer; public float SwingMinAngle { get; set; } = -30f; public float SwingMaxAngle { get; set; } = 30f; private void Start() { //IL_0007: 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_0011: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) _startPos = Vector2.op_Implicit(((Component)this).transform.position); _startAngle = ((Component)this).transform.eulerAngles.z; _originalScale = ((Component)this).transform.localScale; _originalPos = ((Component)this).transform.position; _spriteRenderer = ((Component)this).GetComponent(); switch (style) { case MoveStyle.SurfacePatrol: (_leftEdge, _rightEdge) = ScanPlatformEdges(_startPos); break; case MoveStyle.ZigzagLoop: if (Random.value < 0.5f) { _path = GeneratePresetPath(_startPos); } else { _path = GenerateZigzagLoop(_startPos, 5, 10, 8f, 6f); } break; case MoveStyle.Spin: _spinDir = ((Random.Range(0, 2) == 0) ? 1 : (-1)); break; case MoveStyle.Pulse: _pulseTimer = Random.Range(0f, 2f); break; case MoveStyle.Flicker: _flickerTimer = Random.Range(0f, 3f); break; case MoveStyle.Jitter: _jitterTimer = Random.Range(0f, 1f); break; case MoveStyle.Bounce: _bounceTimer = Random.Range(0f, (float)Math.PI * 2f); break; } UpdateSpeed(); } private void Update() { UpdateSpeed(); switch (style) { case MoveStyle.SurfacePatrol: DoSurfacePatrol(); break; case MoveStyle.ZigzagLoop: DoZigzagLoop(); break; case MoveStyle.NeedleSwing: DoNeedleSwing(); break; case MoveStyle.Spin: DoSpin(); break; case MoveStyle.Pulse: DoPulse(); break; case MoveStyle.Flicker: DoFlicker(); break; case MoveStyle.Jitter: DoJitter(); break; case MoveStyle.Bounce: DoBounce(); break; } } private void UpdateSpeed() { _currentSpeed = personality switch { TrapPersonality.Friendly => baseSpeed * (0.15f + Random.value * 0.1f), TrapPersonality.Playful => baseSpeed * (0.6f + Random.value * 0.4f), TrapPersonality.Sinister => UpdateSinisterSpeed(), _ => _currentSpeed, }; } private float UpdateSinisterSpeed() { _cycleCount++; if (_cycleCount >= 180) { _cycleCount = 0; return baseSpeed * ((Random.value > 0.5f) ? 0.75f : 0.15f); } return _currentSpeed; } private void DoSurfacePatrol() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) Vector2 val = ((_moveDir > 0) ? _rightEdge : _leftEdge); ((Component)this).transform.position = Vector2.op_Implicit(Vector2.MoveTowards(Vector2.op_Implicit(((Component)this).transform.position), val, _currentSpeed * Time.deltaTime)); if (Vector2.Distance(Vector2.op_Implicit(((Component)this).transform.position), val) < 0.1f) { _moveDir *= -1; } } private (Vector2 left, Vector2 right) ScanPlatformEdges(Vector2 origin) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_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_0089: Unknown result type (might be due to invalid IL or missing references) //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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) int mask = LayerMask.GetMask(new string[1] { "Terrain" }); float num = origin.y + 0.5f; float num2 = origin.x; float num3 = origin.x; for (int i = 0; i < 40; i++) { if (!RaycastHit2D.op_Implicit(Physics2D.Raycast(new Vector2(num2 - 0.5f, num), Vector2.down, 1f, mask))) { break; } num2 -= 0.5f; } for (int j = 0; j < 40; j++) { if (!RaycastHit2D.op_Implicit(Physics2D.Raycast(new Vector2(num3 + 0.5f, num), Vector2.down, 1f, mask))) { break; } num3 += 0.5f; } return (new Vector2(num2, origin.y), new Vector2(num3, origin.y)); } private void DoZigzagLoop() { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) if (_path != null && _path.Count >= 2) { _pathProgress += _currentSpeed * Time.deltaTime; while (_pathProgress > 1f && _pathIndex < _path.Count - 1) { _pathProgress -= 1f; _pathIndex++; } if (_pathIndex >= _path.Count - 1) { _pathIndex = 0; _pathProgress = 0f; } ((Component)this).transform.position = Vector2.op_Implicit(Vector2.Lerp(_path[_pathIndex], _path[_pathIndex + 1], _pathProgress)); } } private void DoNeedleSwing() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) _swingTimer += Time.deltaTime * _currentSpeed; float num = Mathf.Lerp(SwingMinAngle, SwingMaxAngle, (Mathf.Sin(_swingTimer) + 1f) / 2f); ((Component)this).transform.rotation = Quaternion.Euler(0f, 0f, _startAngle + num); } private void DoSpin() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) _spinAngle += 90f * _currentSpeed * Time.deltaTime * (float)_spinDir; ((Component)this).transform.rotation = Quaternion.Euler(0f, 0f, _spinAngle); } private void DoPulse() { //IL_003e: 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) _pulseTimer += Time.deltaTime * _currentSpeed * 2f; float num = 1f + Mathf.Sin(_pulseTimer) * 0.2f; ((Component)this).transform.localScale = _originalScale * num; } private void DoFlicker() { _flickerTimer += Time.deltaTime * _currentSpeed; float num = 0.5f; bool flag = Mathf.FloorToInt(_flickerTimer / num) % 2 == 0; if (flag != _isVisible) { _isVisible = flag; if ((Object)(object)_spriteRenderer != (Object)null) { ((Renderer)_spriteRenderer).enabled = _isVisible; } else { ((Component)this).gameObject.SetActive(_isVisible); } } } private void DoJitter() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) _jitterTimer += Time.deltaTime * 10f; float num = (Mathf.PerlinNoise(_jitterTimer, 0f) - 0.5f) * 0.2f; float num2 = (Mathf.PerlinNoise(0f, _jitterTimer) - 0.5f) * 0.2f; ((Component)this).transform.position = _originalPos + new Vector3(num, num2, 0f); } private void DoBounce() { //IL_005a: Unknown result type (might be due to invalid IL or missing references) _bounceTimer += Time.deltaTime * _currentSpeed * 2f; float num = Mathf.Sin(_bounceTimer) * 0.3f; ((Component)this).transform.position = new Vector3(_originalPos.x, _originalPos.y + num, _originalPos.z); } private static List GeneratePresetPath(Vector2 origin) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) List>> list = new List>> { () => Square(origin, 4f), () => Hexagon(origin, 4f), () => Hexagram(origin, 4f), () => Triangle(origin, 4f), () => Pentagram(origin, 4f), () => Circle(origin, 4f, 14), () => Figure8(origin, 4f, 12), () => Diamond(origin, 4f), () => Cross(origin, 4f) }; return list[Random.Range(0, list.Count)](); } private static List Square(Vector2 o, float r) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) return new List { o + new Vector2(0f - r, r), o + new Vector2(r, r), o + new Vector2(r, 0f - r), o + new Vector2(0f - r, 0f - r), o + new Vector2(0f - r, r), o }; } private static List Hexagon(Vector2 o, float r) { //IL_0020: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i <= 6; i++) { float num = (float)Math.PI / 180f * (60f * (float)i - 30f); list.Add(o + new Vector2(Mathf.Cos(num) * r, Mathf.Sin(num) * r)); } list.Add(o); return list; } private static List Hexagram(Vector2 o, float r) { //IL_0020: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i < 6; i++) { float num = (float)Math.PI / 180f * (60f * (float)i - 90f); list.Add(o + new Vector2(Mathf.Cos(num) * r, Mathf.Sin(num) * r)); } list.Add(o); return list; } private static List Triangle(Vector2 o, float r) { //IL_0020: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i < 3; i++) { float num = (float)Math.PI / 180f * (120f * (float)i - 90f); list.Add(o + new Vector2(Mathf.Cos(num) * r, Mathf.Sin(num) * r)); } list.Add(o); return list; } private static List Pentagram(Vector2 o, float r) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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) List list = new List(); float num = r * 0.382f; for (int i = 0; i < 5; i++) { float num2 = (float)Math.PI / 180f * (72f * (float)i - 90f); list.Add(o + new Vector2(Mathf.Cos(num2) * r, Mathf.Sin(num2) * r)); list.Add(o + new Vector2(Mathf.Cos(num2 + (float)Math.PI / 5f) * num, Mathf.Sin(num2 + (float)Math.PI / 5f) * num)); } list.Add(o); return list; } private static List Circle(Vector2 o, float r, int segments) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i <= segments; i++) { float num = (float)Math.PI / 180f * (360f * (float)i / (float)segments); list.Add(o + new Vector2(Mathf.Cos(num) * r, Mathf.Sin(num) * r)); } list.Add(o); return list; } private static List Figure8(Vector2 o, float r, int segments) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_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_009d: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i <= segments / 2; i++) { float num = (float)Math.PI / 180f * (360f * (float)i / (float)segments); list.Add(o + new Vector2(r + Mathf.Cos(num) * r, Mathf.Sin(num) * r * 1.5f)); } for (int j = segments / 2; j <= segments; j++) { float num2 = (float)Math.PI / 180f * (360f * (float)j / (float)segments); list.Add(o + new Vector2(0f - r + Mathf.Cos(num2) * r, Mathf.Sin(num2) * r * 1.5f)); } list.Add(o); return list; } private static List Diamond(Vector2 o, float r) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) return new List { o + new Vector2(0f, r), o + new Vector2(r, 0f), o + new Vector2(0f, 0f - r), o + new Vector2(0f - r, 0f), o + new Vector2(0f, r), o }; } private static List Cross(Vector2 o, float r) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0090: 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_009f: 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_00af: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) float num = r * 0.4f; return new List { o + new Vector2(0f, r), o + new Vector2(num, r * 0.6f), o + new Vector2(num, num), o + new Vector2(r * 0.6f, num), o + new Vector2(r, 0f), o + new Vector2(r * 0.6f, 0f - num), o + new Vector2(num, 0f - num), o + new Vector2(num, (0f - r) * 0.6f), o + new Vector2(0f, 0f - r), o + new Vector2(0f - num, (0f - r) * 0.6f), o + new Vector2(0f - num, 0f - num), o + new Vector2((0f - r) * 0.6f, 0f - num), o + new Vector2(0f - r, 0f), o + new Vector2((0f - r) * 0.6f, num), o + new Vector2(0f - num, num), o + new Vector2(0f - num, r * 0.6f), o }; } private static List GenerateZigzagLoop(Vector2 start, int minSeg, int maxSeg, float maxW, float maxH) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) Random random = new Random(); int num = random.Next(minSeg, maxSeg); List list = new List { start }; float num2 = start.x; float num3 = start.y; for (int i = 0; i < num - 1; i++) { float num4 = (float)((random.Next(2) == 0) ? 1 : (-1)) * (5f + (float)random.NextDouble() * 7f); float num5 = (float)((random.Next(2) == 0) ? 1 : (-1)) * (3f + (float)random.NextDouble() * 5f); num2 += num4; num3 += num5; list.Add(new Vector2(num2, num3)); } list.Add(start); return list; } } public static class TrapMovement { private const float GlobalMoveChance = 0.4f; private static readonly List AllStyles = new List { MoveStyle.SurfacePatrol, MoveStyle.ZigzagLoop, MoveStyle.NeedleSwing, MoveStyle.Spin, MoveStyle.Pulse, MoveStyle.Flicker, MoveStyle.Jitter, MoveStyle.Bounce }; private static readonly HashSet ExcludedTraps = new HashSet { "lava_area" }; public static void ApplyTrapMovement(GameObject trapObj, string trapId, Random rng) { if (!ExcludedTraps.Contains(trapId) && !(rng.NextDouble() > 0.4000000059604645)) { MoveStyle moveStyle = AllStyles[rng.Next(AllStyles.Count)]; TrapPersonality personality = (TrapPersonality)rng.Next(0, 3); TrapMover trapMover = trapObj.AddComponent(); trapMover.style = moveStyle; trapMover.personality = personality; trapMover.baseSpeed = 2f; if (moveStyle == MoveStyle.NeedleSwing) { trapMover.SwingMinAngle = -30f + (float)rng.NextDouble() * 10f - 5f; trapMover.SwingMaxAngle = 30f + (float)rng.NextDouble() * 10f - 5f; } } } } public static class TrapPreloader { public enum TrapDifficulty { Beginner, Focused, Overflow } public static readonly List TrapPool = new List { "fan_hazard", "spike_cog_1", "spike_cog_2", "spike_cog_3", "spike_cog_4", "spike_cog_5", "hot_coal", "lava_area", "falling_lava", "bone_boulder", "hunter_landmine", "pilgrim_trap_spike", "wisp_flame_lantern", "falling_bell", "shellwood_thorns", "coral_lightning_rock", "coral_lightning_orb", "voltgrass", "coral_crust_s", "coral_crust_m", "coral_crust_l", "coral_spike", "coral_spike_fall", "stomp_spire", "rubble_field", "steam_vent", "junk_pipe", "slab_trap", "slab_spike_ball", "slab_prob_blade", "hunter_sickle_trap", "bilewater_trap", "falling_spike_ball", "swing_trap_small", "swing_trap_spike", "dust_trap_spike_plate", "dust_trap_spike_dropper", "mite_trap", "organ_spikes", "cradle_spikes", "brown_vines", "abyss_tendrils", "void_wave", "mill_trap", "craw_chain", "frost_marker", "white_thorns", "jelly_egg", "wp_trap_spikes" }; public static readonly HashSet ExcludedScenes = new HashSet(StringComparer.OrdinalIgnoreCase) { "Belltown_04", "Bellshrine", "Bellshrine_02", "Bellshrine_03", "Bellshrine_05", "Bone_East_Umbrella", "Room_Pinstress" }; public static readonly HashSet NoLavaScenes = new HashSet(StringComparer.OrdinalIgnoreCase) { "Hang_01", "Hang_02", "Hang_10" }; public static readonly HashSet LargeRooms = new HashSet(StringComparer.OrdinalIgnoreCase) { "Song_20", "Arborium_01", "Cog_04", "Song_11", "Song_05", "Song_01", "Coral_35b" }; public static readonly HashSet LargeTraps = new HashSet(StringComparer.OrdinalIgnoreCase) { "fan_hazard", "steam_vent", "mill_trap", "spike_cog_2", "spike_cog_3", "spike_cog_1", "spike_cog_4", "spike_cog_5", "voltgrass", "junk_pipe" }; public static readonly HashSet ThornTraps = new HashSet(StringComparer.OrdinalIgnoreCase) { "brown_vines", "shellwood_thorns", "white_thorns" }; public static readonly HashSet SmallPlatforms = new HashSet(StringComparer.OrdinalIgnoreCase) { "small_grey_coral_plat", "small_red_coral_plat", "shell_small" }; public static readonly HashSet LoweredSpikeTraps = new HashSet(StringComparer.OrdinalIgnoreCase) { "pilgrim_trap_spike", "organ_spikes", "cradle_spikes" }; public static readonly HashSet HammerTraps = new HashSet(StringComparer.OrdinalIgnoreCase) { "slab_spike_ball" }; public const string LavaTrapId = "lava_area"; public const string FallingLavaId = "falling_lava"; public const float MinDistance = 8f; public const float PickupSafeRadius = 5f; public const float DoorSafeRadius = 7f; public const int LargeTrapRadius = 5; public const float LargeTrapYOffset = 1.5f; public const int ThornTrapMinWidth = 4; public const float SpikeYOffset = 1.8f; public const int HammerTrapMinHeight = 7; public const float WallPointMatchDistance = 1f; public const float DarkThunderChainDistance = 4f; public const int MaxDarkThunderCount = 4; public static readonly Dictionary TrapMetaDict = new Dictionary { ["fan_hazard"] = new TrapMeta(), ["spike_cog_1"] = new TrapMeta(), ["spike_cog_2"] = new TrapMeta(), ["spike_cog_3"] = new TrapMeta(), ["spike_cog_4"] = new TrapMeta(), ["spike_cog_5"] = new TrapMeta(), ["hot_coal"] = new TrapMeta(), ["lava_area"] = new TrapMeta(), ["falling_lava"] = new TrapMeta(), ["voltgrass"] = new TrapMeta(), ["steam_vent"] = new TrapMeta(), ["slab_trap"] = new TrapMeta(), ["slab_prob_blade"] = new TrapMeta(), ["slab_spike_ball"] = new TrapMeta(), ["dust_trap_spike_plate"] = new TrapMeta(), ["dust_trap_spike_dropper"] = new TrapMeta(), ["mite_trap"] = new TrapMeta(), ["organ_spikes"] = new TrapMeta(), ["cradle_spikes"] = new TrapMeta(), ["mill_trap"] = new TrapMeta(), ["coral_lightning_rock"] = new TrapMeta(), ["coral_crust_s"] = new TrapMeta(), ["coral_crust_m"] = new TrapMeta(), ["coral_crust_l"] = new TrapMeta(), ["abyss_tendrils"] = new TrapMeta(), ["bone_boulder"] = new TrapMeta(), ["void_wave"] = new TrapMeta(), ["coral_lightning_orb"] = new TrapMeta(), ["wisp_flame_lantern"] = new TrapMeta(new Dictionary { ["breakable_on"] = "True" }), ["falling_bell"] = new TrapMeta(new Dictionary { ["bell_reset"] = "1" }), ["shellwood_thorns"] = new TrapMeta(new Dictionary { ["vines_hurt_player"] = "True" }), ["brown_vines"] = new TrapMeta(new Dictionary { ["vines_hurt_player"] = "True" }), ["white_thorns"] = new TrapMeta(new Dictionary { ["vines_hurt_player"] = "True" }), ["junk_pipe"] = new TrapMeta(new Dictionary { ["junk_pipe_terrain"] = "True" }), ["frost_marker"] = new TrapMeta(new Dictionary { ["frost_speed"] = "10" }), ["jelly_egg"] = new TrapMeta(new Dictionary { ["egg_regen"] = "-1" }), ["wp_trap_spikes"] = new TrapMeta(new Dictionary { ["wp_spikes_up"] = "True", ["wp_spikes_delay"] = "0", ["wp_spikes_speed"] = "1" }, needsActivator: false, (string)null, (Vector3?)new Vector3(0f, 5f, 0f), (Vector3?)null), ["pilgrim_trap_spike"] = new TrapMeta(null, needsActivator: true, "pilgrim_trap_wire"), ["rubble_field"] = new TrapMeta((Dictionary)null, needsActivator: true, "slab_pressure_plate", (Vector3?)new Vector3(0f, 0.5f, 0f), (Vector3?)null), ["bilewater_trap"] = new TrapMeta((Dictionary)null, needsActivator: true, "slab_pressure_plate", (Vector3?)new Vector3(10f, 0f, 0f), (Vector3?)null), ["falling_spike_ball"] = new TrapMeta(null, needsActivator: true, "slab_pressure_plate"), ["swing_trap_small"] = new TrapMeta((Dictionary)null, needsActivator: true, "slab_pressure_plate", (Vector3?)new Vector3(0f, 8f, 0f), (Vector3?)null), ["swing_trap_spike"] = new TrapMeta((Dictionary)null, needsActivator: true, "slab_pressure_plate", (Vector3?)new Vector3(0f, 15f, 0f), (Vector3?)null), ["hunter_landmine"] = new TrapMeta((Dictionary)null, needsActivator: true, "hunter_trap_plate", (Vector3?)new Vector3(0f, -1f, 0f), (Vector3?)new Vector3(0f, 0f, 180f)), ["hunter_sickle_trap"] = new TrapMeta((Dictionary)null, needsActivator: true, "hunter_trap_plate", (Vector3?)new Vector3(0f, 6f, 0f), (Vector3?)null), ["craw_chain"] = new TrapMeta(null, needsActivator: true, "trigger_zone"), ["coral_spike"] = new TrapMeta(null, needsActivator: true, "trigger_zone"), ["coral_spike_fall"] = new TrapMeta(null, needsActivator: true, "trigger_zone"), ["stomp_spire"] = new TrapMeta(null, needsActivator: true, "trigger_zone") }; public static readonly Dictionary> TrapCategories = new Dictionary> { ["暗雷"] = new List { "hunter_landmine", "dust_trap_spike_plate", "slab_trap", "slab_prob_blade", "hunter_sickle_trap" }, ["跳跳乐"] = new List { "spike_cog_1", "spike_cog_2", "spike_cog_3", "spike_cog_4", "spike_cog_5" }, ["平台类"] = new List { "spike_cog_1", "spike_cog_2", "spike_cog_3", "spike_cog_4", "spike_cog_5", "fan_hazard", "mill_trap" }, ["尖刺类"] = new List { "wp_trap_spikes", "organ_spikes", "coral_spike", "pilgrim_trap_spike", "cradle_spikes", "slab_spike_ball" }, ["墙壁"] = new List(), ["天花板"] = new List { "falling_bell", "bone_boulder", "dust_trap_spike_dropper", "falling_lava", "coral_lightning_orb", "coral_lightning_rock", "steam_vent", "junk_pipe" }, ["障碍物"] = new List { "coral_crust_s", "coral_crust_m", "coral_crust_l", "hot_coal", "march_pogo", "bounce_bloom", "wisp_bounce_pod", "sprintmaster_pod", "swap_bounce_pod", "celeste_bumper" }, ["装饰物"] = new List { "clover_pod", "abyss_pod", "lilypad", "cradle_nut", "karaka_statue", "judge_statue", "clover_statue", "shard_statue_1", "shard_statue_2", "shard_statue_3", "shard_statue_4", "shard_statue_5", "flick_statue", "fayforn_npc", "snow_chunk", "float_crystal", "white_palace_fly", "pond_skipper_body", "winged_lifeseed", "life_pustule", "bounce_flea", "dodge_flea", "hornet_cocoon", "bellbeast_child", "bell_s", "bell_l", "bell_lock", "greymoor_balloon_small", "greymoor_balloon_mid", "greymoor_balloon_large", "swamp_mosquito", "swamp_mosquito_skinny", "mothleaf", "imoba", "garpid", "crystal_drifter", "crystal_drifter_giant", "stilkin", "stilkin_trapper", "dock_bomber" }, ["触发型"] = new List { "swing_trap_small", "coral_spike_fall", "stomp_spire", "falling_spike_ball", "rubble_field", "mite_trap", "bilewater_trap", "craw_chain", "swing_trap_spike" }, ["追逐型"] = new List { "wisp_flame_lantern" }, ["场景伤害"] = new List { "abyss_tendrils", "voltgrass", "void_wave", "frost_marker" }, ["跳跳乐1"] = new List { "march_pogo", "bounce_bloom", "wisp_bounce_pod", "sprintmaster_pod", "swap_bounce_pod", "clover_pod", "abyss_pod", "celeste_bumper", "lilypad", "cradle_nut", "karaka_statue", "judge_statue", "clover_statue", "shard_statue_1", "shard_statue_2", "shard_statue_3", "shard_statue_4", "shard_statue_5", "flick_statue", "fayforn_npc", "snow_chunk", "float_crystal", "white_palace_fly", "pond_skipper_body", "winged_lifeseed", "life_pustule", "bounce_flea", "dodge_flea", "hornet_cocoon", "bellbeast_child", "bell_s", "bell_l", "bell_lock", "greymoor_balloon_small", "greymoor_balloon_mid", "greymoor_balloon_large", "swamp_mosquito", "swamp_mosquito_skinny", "mothleaf", "imoba", "garpid", "crystal_drifter", "crystal_drifter_giant", "stilkin", "stilkin_trapper", "dock_bomber" }, ["平台类1"] = new List { "coral_plat_float", "small_grey_coral_plat", "small_red_coral_plat", "mid_red_coral_plat", "large_red_coral_plat", "abyss_plat_mid", "abyss_plat_wide", "deepnest_platform_01", "deepnest_platform_02", "deepnest_platform_03", "deepnest_platform_04", "deepnest_platform_05", "hive_platform_01", "hive_platform_02", "hive_platform_03", "shell_small", "shell_mid", "shell_large" } }; private static readonly Dictionary> Quotas = new Dictionary> { [TrapDifficulty.Beginner] = new Dictionary { ["暗雷"] = 2, ["跳跳乐"] = 1, ["平台类"] = 2, ["尖刺类"] = 2, ["墙壁"] = 0, ["天花板"] = 5, ["障碍物"] = 4, ["装饰物"] = 3, ["触发型"] = 5, ["追逐型"] = 0, ["场景伤害"] = 0 }, [TrapDifficulty.Focused] = new Dictionary { ["暗雷"] = 4, ["跳跳乐"] = 3, ["平台类"] = 4, ["尖刺类"] = 4, ["墙壁"] = 0, ["天花板"] = 6, ["障碍物"] = 5, ["装饰物"] = 4, ["触发型"] = 6, ["追逐型"] = 1, ["场景伤害"] = 1 }, [TrapDifficulty.Overflow] = new Dictionary { ["暗雷"] = 6, ["跳跳乐"] = 5, ["平台类"] = 6, ["尖刺类"] = 6, ["墙壁"] = 0, ["天花板"] = 8, ["障碍物"] = 6, ["装饰物"] = 5, ["触发型"] = 8, ["追逐型"] = 2, ["场景伤害"] = 2 } }; public static readonly string[] CategoryOrder = new string[11] { "暗雷", "跳跳乐", "平台类", "尖刺类", "墙壁", "天花板", "障碍物", "装饰物", "触发型", "追逐型", "场景伤害" }; public static List TrapPoolNoLava => TrapPool.Where((string t) => t != "lava_area").ToList(); public static Dictionary GetCategoryQuotas(TrapDifficulty difficulty) { if (!Quotas.TryGetValue(difficulty, out var value)) { return new Dictionary(Quotas[TrapDifficulty.Beginner]); } return new Dictionary(value); } public static double GetFrostProbability(TrapDifficulty difficulty) { return difficulty switch { TrapDifficulty.Focused => 0.1, TrapDifficulty.Overflow => 0.2, _ => 0.0, }; } } public class TrapMeta { public Dictionary Config { get; set; } public bool NeedsActivator { get; set; } public string ActivatorId { get; set; } public Vector3 PositionOffset { get; set; } public Vector3 PositionRotate { get; set; } public TrapMeta(Dictionary config = null, bool needsActivator = false, string activatorId = null, Vector3? positionOffset = null, Vector3? positionRotate = null) { //IL_003a: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Config = config ?? new Dictionary(); NeedsActivator = needsActivator; ActivatorId = activatorId; PositionOffset = (Vector3)(((??)positionOffset) ?? Vector3.zero); PositionRotate = (Vector3)(((??)positionRotate) ?? Vector3.zero); } } public class TrapRandomConfig { public int Seed; public bool Enabled; public bool MovementEnabled = true; public int Difficulty; public HashSet FrostBannedScenes = new HashSet(); } public static class TrapRandomizer { public class OneTimeTrap : MonoBehaviour { [CompilerGenerated] private sealed class d__6 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public OneTimeTrap <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; OneTimeTrap oneTimeTrap = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; Object.Destroy((Object)(object)((Component)oneTimeTrap).gameObject); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private bool _triggered; private const float Lifetime = 3f; private void Start() { Object.Destroy((Object)(object)((Component)this).gameObject, 3f); } private void OnTriggerEnter2D(Collider2D other) { if (!_triggered && ((Component)other).CompareTag("Player")) { DestroySelf(); } } private void OnCollisionEnter2D(Collision2D collision) { if (!_triggered && collision.gameObject.CompareTag("Player")) { DestroySelf(); } } private void DestroySelf() { if (!_triggered) { _triggered = true; ((MonoBehaviour)this).StartCoroutine(DestroyNextFrame()); } } [IteratorStateMachine(typeof(d__6))] private IEnumerator DestroyNextFrame() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { <>4__this = this }; } } private static bool _initialized = false; private static bool _enabled = false; private static bool _movementEnabled = true; private static int _difficulty = 0; private static int _masterSeed; private static Random _rng; private static readonly List ActiveTraps = new List(); private static HashSet _frostBannedScenes = new HashSet(); private static List _surfacePoints = new List(); private static List _ceilingPoints = new List(); private static List _wallPoints = new List(); private static List<(Vector3 center, float minX, float maxX, float waterY)> _waterRegions = new List<(Vector3, float, float, float)>(); private static List _doorPositions = new List(); private static List<(Vector3 pos, Bounds? bounds)> _pickupData = new List<(Vector3, Bounds?)>(); private static string _lastScene = ""; private static readonly Dictionary> _cachedTraps = new Dictionary>(); private static readonly Dictionary> _cachedBounceObjects = new Dictionary>(); private static readonly Dictionary> _cachedPlatforms = new Dictionary>(); private static readonly Dictionary _lastSceneFrostRecord = new Dictionary(); private static int _chasingTrapsInScene = 0; public static bool Enabled { get { return _enabled; } set { if (_enabled != value) { _enabled = value; if (_enabled) { SpawnTraps(); } else { ClearAll(); } } } } public static bool MovementEnabled { get { return _movementEnabled; } set { if (_movementEnabled != value) { _movementEnabled = value; if (_enabled) { ClearAll(); SpawnTraps(); } } } } public static int CurrentDifficulty { get { return _difficulty; } set { if (_difficulty != value) { _difficulty = value; if (_enabled) { ClearAll(); SpawnTraps(); } } } } public static void Initialize(TrapRandomConfig config) { if (config != null) { _masterSeed = config.Seed; _enabled = config.Enabled; _movementEnabled = config.MovementEnabled; _difficulty = config.Difficulty; _frostBannedScenes = config.FrostBannedScenes ?? new HashSet(); _rng = new Random(_masterSeed); _initialized = true; Plugin.Log.LogInfo((object)$"陷阱随机系统初始化: 种子={_masterSeed}, 难度={_difficulty}, 移动={_movementEnabled}"); } } public static void Reconfigure(bool enabled, bool movementEnabled, int difficulty) { bool enabled2 = _enabled; _enabled = enabled; _movementEnabled = movementEnabled; _difficulty = difficulty; if (_enabled) { if (!enabled2) { ClearAll(); SpawnTraps(); } else { ClearAll(); SpawnTraps(); } } else { ClearAll(); } } public static void SetFrostBannedScenes(HashSet bannedScenes) { _frostBannedScenes = bannedScenes ?? new HashSet(); } public static void ResetFrostBannedScenes() { _frostBannedScenes.Clear(); } public static void SpawnTraps() { //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_05f3: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_0609: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_06ca: Unknown result type (might be due to invalid IL or missing references) //IL_06cf: Unknown result type (might be due to invalid IL or missing references) //IL_06ef: Unknown result type (might be due to invalid IL or missing references) //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_0718: Unknown result type (might be due to invalid IL or missing references) //IL_0787: Unknown result type (might be due to invalid IL or missing references) //IL_078c: Unknown result type (might be due to invalid IL or missing references) //IL_0846: Unknown result type (might be due to invalid IL or missing references) //IL_0854: Unknown result type (might be due to invalid IL or missing references) //IL_0744: Unknown result type (might be due to invalid IL or missing references) //IL_087e: Unknown result type (might be due to invalid IL or missing references) //IL_0870: Unknown result type (might be due to invalid IL or missing references) //IL_07d8: Unknown result type (might be due to invalid IL or missing references) //IL_07df: Unknown result type (might be due to invalid IL or missing references) //IL_07e5: Unknown result type (might be due to invalid IL or missing references) if (!_initialized || !_enabled || (Object)(object)HeroController.instance == (Object)null) { return; } string text = GameManager.instance?.sceneName ?? ""; if (TrapPreloader.ExcludedScenes.Contains(text)) { _cachedTraps.Remove(text); return; } ClearAll(); ScanSceneSurfaces(); Random random = new Random(_masterSeed ^ text.GetHashCode()); float minY = ((_surfacePoints.Count > 0) ? _surfacePoints.Min((Vector3 p) => p.y) : 0f); double frostProbability = GetFrostProbability(_difficulty); _chasingTrapsInScene = 0; List<(Vector3, bool)> list = new List<(Vector3, bool)>(); list.AddRange(_surfacePoints.Select((Vector3 p) => (p, false))); list.AddRange(_ceilingPoints.Select((Vector3 p) => (p, true))); Dictionary quotas = TrapPreloader.GetCategoryQuotas((TrapPreloader.TrapDifficulty)_difficulty); List<(Vector3, string)> value; bool flag = ((!_cachedTraps.TryGetValue(text, out value) || !value.Any(((Vector3, string) c) => c.Item2 == "frost_marker")) ? (!_lastSceneFrostRecord.ContainsKey(text) && frostProbability > 0.0 && !_frostBannedScenes.Contains(text) && random.NextDouble() < frostProbability) : (!_lastSceneFrostRecord.ContainsKey(text) || !_lastSceneFrostRecord[text])); if (_cachedTraps.TryGetValue(text, out var value2)) { List<(Vector3, string)> obj = (flag ? value2 : value2.Where(((Vector3, string) c) => c.Item2 != "frost_marker").ToList()); List<(Vector3, string)> list2 = new List<(Vector3, string)>(); List list3 = new List(); bool value3 = false; foreach (var item5 in obj) { Vector3 pos = item5.Item1; string item = item5.Item2; bool isCeiling = _ceilingPoints.Any((Vector3 p) => Vector3.Distance(p, pos) < 0.5f); string categoryForTrapId = GetCategoryForTrapId(item); if (!list3.Any((Vector3 u) => Vector3.Distance(pos, u) < 8f) && !_doorPositions.Any((Vector2 d) => Vector2.Distance(Vector2.op_Implicit(pos), d) < 7f) && IsTrapAllowed(item, pos, text, minY, isCeiling, categoryForTrapId)) { list2.Add((pos, item)); list3.Add(pos); if (item == "frost_marker") { value3 = true; } } } int num = TrapPreloader.CategoryOrder.Where((string c) => c != "场景伤害").Sum((string c) => quotas.ContainsKey(c) ? quotas[c] : 0); if ((float)list2.Count >= (float)num * 0.8f) { ShuffleList(list2, random); foreach (var item6 in list2) { var (pos2, _) = item6; ArchitectSpawn(item6.Item2, pos2); } _lastSceneFrostRecord[text] = value3; SpawnBounceObjects(random, text); SpawnPlatforms(random, text); return; } _cachedTraps.Remove(text); } List<(string, string)> list4 = new List<(string, string)>(); string[] categoryOrder = TrapPreloader.CategoryOrder; foreach (string text2 in categoryOrder) { if (!TrapPreloader.TrapCategories.TryGetValue(text2, out var value4) || value4.Count == 0) { continue; } int num2 = (quotas.ContainsKey(text2) ? quotas[text2] : 0); if (text2 == "追逐型" && _chasingTrapsInScene >= 1) { continue; } for (int j = 0; j < num2; j++) { if (text2 == "场景伤害" && _waterRegions.Count == 0) { continue; } string text3; if (!(text2 == "场景伤害")) { text3 = ((!(random.NextDouble() < 0.7)) ? TrapPreloader.TrapPoolNoLava[random.Next(TrapPreloader.TrapPoolNoLava.Count)] : value4[random.Next(value4.Count)]); } else { if (random.NextDouble() >= 0.05) { continue; } text3 = value4[random.Next(value4.Count)]; } if (!(text3 == "frost_marker") || flag) { list4.Add((text3, text2)); } } } if (_waterRegions.Count > 0 && random.NextDouble() < 0.3 && !TrapPreloader.NoLavaScenes.Contains(text)) { list4.Add(("lava_area", "场景伤害")); } ShuffleList(list4, random); List list5 = new List(); List list6 = new List(); List<(Vector3, string)> list7 = new List<(Vector3, string)>(); bool value5 = false; foreach (var item7 in list4) { string item2 = item7.Item1; string item3 = item7.Item2; if (item3 == "暗雷" && list6.Count >= 4) { continue; } List list8 = new List(); bool flag2 = item3 == "天花板"; foreach (var (item4, flag3) in list) { if (flag2 == flag3) { list8.Add(item4); } } if (item3 == "暗雷" && list6.Count > 0) { List list9 = new List(); foreach (Vector3 darkPos in list6) { list9.AddRange(list8.Where((Vector3 pt) => Vector2.Distance(Vector2.op_Implicit(pt), Vector2.op_Implicit(darkPos)) <= 4f)); } list8 = list9.Distinct().ToList(); } List list10 = new List(); foreach (Vector3 pt2 in list8) { if (!_doorPositions.Any((Vector2 d) => Vector2.Distance(Vector2.op_Implicit(pt2), d) < 7f) && !IsTooCloseToPickup(pt2)) { bool isCeiling2 = _ceilingPoints.Any((Vector3 cp) => Vector2.Distance(Vector2.op_Implicit(cp), Vector2.op_Implicit(pt2)) < 0.5f); if (IsTrapAllowed(item2, pt2, text, minY, isCeiling2, item3) && !list5.Any((Vector3 u) => Vector2.Distance(Vector2.op_Implicit(pt2), Vector2.op_Implicit(u)) < 8f)) { list10.Add(pt2); } } } if (list10.Count == 0) { continue; } Vector3 chosen = list10[random.Next(list10.Count)]; if (item2 == "lava_area" && _waterRegions.Count > 0) { (Vector3, float, float, float) tuple3 = _waterRegions.FirstOrDefault(((Vector3 center, float minX, float maxX, float waterY) w) => chosen.x >= w.minX && chosen.x <= w.maxX); ref Vector3 reference = ref chosen; (Vector3, float, float, float) tuple4 = tuple3; reference.y = ((tuple4.Item1 != default(Vector3) || tuple4.Item2 != 0f || tuple4.Item3 != 0f || tuple4.Item4 != 0f) ? (tuple3.Item4 - 3f) : (_waterRegions[0].waterY - 3f)); } ArchitectSpawn(item2, chosen); list5.Add(chosen); if (item3 == "暗雷") { list6.Add(chosen); } list7.Add((chosen, item2)); if (item2 == "frost_marker") { value5 = true; } if (item3 == "追逐型") { _chasingTrapsInScene++; } } if (list7.Count > 0) { _cachedTraps[text] = list7; } _lastSceneFrostRecord[text] = value5; SpawnBounceObjects(random, text); SpawnPlatforms(random, text); } public static void ClearAll() { foreach (GameObject activeTrap in ActiveTraps) { if (Object.op_Implicit((Object)(object)activeTrap)) { Object.Destroy((Object)(object)activeTrap); } } ActiveTraps.Clear(); } public static void ClearAndRescan() { ClearAll(); _surfacePoints.Clear(); _ceilingPoints.Clear(); _wallPoints.Clear(); _waterRegions.Clear(); _doorPositions.Clear(); _pickupData.Clear(); _lastScene = ""; } public static void RespawnTraps() { if (_enabled) { ClearAndRescan(); SpawnTraps(); } } private static void ScanSceneSurfaces() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_02c4: 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_014c: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: 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_0258: Unknown result type (might be due to invalid IL or missing references) _surfacePoints.Clear(); _ceilingPoints.Clear(); HeroController instance = HeroController.instance; Vector2 val = (Object.op_Implicit((Object)(object)instance) ? Vector2.op_Implicit(((Component)instance).transform.position) : Vector2.zero); string text = GameManager.instance?.sceneName ?? ""; bool num = TrapPreloader.LargeRooms.Contains(text); float num2 = (num ? 60f : 120f); float num3 = (num ? 120f : 80f); Vector2 val2 = val + new Vector2(0f - num2, 0f - num3); Vector2 val3 = val + new Vector2(num2, num3); Collider2D[] array = Physics2D.OverlapAreaAll(val2, val3, LayerMask.GetMask(new string[1] { "Terrain" })); int mask = LayerMask.GetMask(new string[1] { "Terrain" }); Collider2D[] array2 = array; Vector2 val5 = default(Vector2); Vector2 val7 = default(Vector2); foreach (Collider2D val4 in array2) { Bounds bounds = val4.bounds; if (((Bounds)(ref bounds)).size.y > ((Bounds)(ref bounds)).size.x * 2f || ((Bounds)(ref bounds)).min.y > val.y + 120f) { continue; } for (float num4 = ((Bounds)(ref bounds)).min.x + 0.5f; num4 <= ((Bounds)(ref bounds)).max.x - 0.5f; num4 += 1f) { ((Vector2)(ref val5))..ctor(num4, ((Bounds)(ref bounds)).max.y + 0.5f); RaycastHit2D val6 = Physics2D.Raycast(val5, Vector2.up, 1.5f, mask); if (Object.op_Implicit((Object)(object)((RaycastHit2D)(ref val6)).collider)) { continue; } val6 = Physics2D.Raycast(val5, Vector2.down, 0.5f, mask); if ((Object)(object)((RaycastHit2D)(ref val6)).collider != (Object)(object)val4) { continue; } _surfacePoints.Add(new Vector3(num4, ((Bounds)(ref bounds)).max.y + 0.5f, 0f)); ((Vector2)(ref val7))..ctor(num4, ((Bounds)(ref bounds)).min.y - 0.5f); val6 = Physics2D.Raycast(val7, Vector2.up, 0.5f, mask); if (!((Object)(object)((RaycastHit2D)(ref val6)).collider != (Object)(object)val4)) { val6 = Physics2D.Raycast(val7, Vector2.down, 1.5f, mask); if (!Object.op_Implicit((Object)(object)((RaycastHit2D)(ref val6)).collider)) { _ceilingPoints.Add(new Vector3(num4, ((Bounds)(ref bounds)).min.y - 0.5f, 0f)); } } } } _doorPositions.Clear(); TransitionPoint[] array3 = Object.FindObjectsOfType(); foreach (TransitionPoint val8 in array3) { _doorPositions.Add(Vector2.op_Implicit(((Component)val8).transform.position)); } ScanPickups(); ScanWaterRegions(); _lastScene = text; } private static void ScanPickups() { //IL_0026: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) _pickupData.Clear(); CollectableItemPickup[] array = Resources.FindObjectsOfTypeAll(); foreach (CollectableItemPickup val in array) { if (Object.op_Implicit((Object)(object)val)) { Scene scene = ((Component)val).gameObject.scene; if (((Scene)(ref scene)).isLoaded) { Collider2D component = ((Component)val).GetComponent(); _pickupData.Add((((Component)val).transform.position, Object.op_Implicit((Object)(object)component) ? new Bounds?(component.bounds) : null)); } } } } private static void ScanWaterRegions() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) _waterRegions.Clear(); SurfaceWaterRegion[] array = Object.FindObjectsOfType(); foreach (SurfaceWaterRegion val in array) { BoxCollider2D component = ((Component)val).GetComponent(); if (Object.op_Implicit((Object)(object)component)) { Bounds bounds = ((Collider2D)component).bounds; _waterRegions.Add((new Vector3((((Bounds)(ref bounds)).min.x + ((Bounds)(ref bounds)).max.x) / 2f, ((Component)val).transform.position.y + 0.4f, 0f), ((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x, ((Component)val).transform.position.y + 0.4f)); } } } private static float GetPlatformWidth(Vector2 pt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) float num = pt.y - 0.2f; float num2 = pt.x; for (int i = 0; i < 20; i++) { RaycastHit2D val = Physics2D.Raycast(new Vector2(num2 - 0.5f, num), Vector2.down, 1f, LayerMask.GetMask(new string[1] { "Terrain" })); if (!Object.op_Implicit((Object)(object)((RaycastHit2D)(ref val)).collider)) { break; } num2 -= 0.5f; } float num3 = pt.x; for (int j = 0; j < 20; j++) { RaycastHit2D val2 = Physics2D.Raycast(new Vector2(num3 + 0.5f, num), Vector2.down, 1f, LayerMask.GetMask(new string[1] { "Terrain" })); if (!Object.op_Implicit((Object)(object)((RaycastHit2D)(ref val2)).collider)) { break; } num3 += 0.5f; } return num3 - num2; } private static bool IsTooCloseToPickup(Vector3 p) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return _pickupData.Any(((Vector3 pos, Bounds? bounds) x) => Vector2.Distance(Vector2.op_Implicit(p), Vector2.op_Implicit(x.pos)) < 5f); } private static bool IsInsidePickupBounds(Vector3 p) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) return _pickupData.Any(delegate((Vector3 pos, Bounds? bounds) x) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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) if (x.bounds.HasValue) { Bounds value = x.bounds.Value; return ((Bounds)(ref value)).Contains(p); } return false; }); } private static bool CanPlaceLargeTrap(Vector2 origin) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) RaycastHit2D val = Physics2D.Raycast(origin, Vector2.down, 2f, LayerMask.GetMask(new string[1] { "Terrain" })); Collider2D collider = ((RaycastHit2D)(ref val)).collider; Collider2D[] array = Physics2D.OverlapCircleAll(origin, 5f, LayerMask.GetMask(new string[1] { "Terrain" })); bool flag = false; bool flag2 = false; Collider2D[] array2 = array; foreach (Collider2D val2 in array2) { if (!((Object)(object)val2 == (Object)(object)collider)) { Bounds bounds = val2.bounds; if (((Bounds)(ref bounds)).max.y > origin.y) { flag = true; } if (((Bounds)(ref bounds)).min.y < origin.y) { flag2 = true; } if (flag && flag2) { return false; } } } return !(flag && flag2); } private static bool IsTrapAllowed(string id, Vector3 pos, string scene, float minY, bool isCeiling, string category) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_0167: Unknown result type (might be due to invalid IL or missing references) if (scene == "Bonetown" && pos.x >= 45f && pos.x <= 82f && pos.y >= 3f && pos.y <= 14f) { return false; } if (id == "lava_area" && TrapPreloader.NoLavaScenes.Contains(scene)) { return false; } if (id == "lava_area" && _waterRegions.Count == 0) { return false; } if (id == "falling_lava" && _doorPositions.Any((Vector2 d) => Mathf.Abs(pos.x - d.x) < 9f)) { return false; } if (id == "frost_marker" && _frostBannedScenes.Contains(scene)) { return false; } if (TrapPreloader.LargeTraps.Contains(id) && !CanPlaceLargeTrap(Vector2.op_Implicit(pos))) { return false; } if (TrapPreloader.HammerTraps.Contains(id) && pos.y - minY < 7f) { return false; } if (category != "墙壁" && TrapPreloader.ThornTraps.Contains(id) && (GetPlatformWidth(Vector2.op_Implicit(pos)) < 4f || !CanPlaceLargeTrap(Vector2.op_Implicit(pos)) || IsInsidePickupBounds(pos))) { return false; } if (id == "cradle_spikes" && GetPlatformWidth(Vector2.op_Implicit(pos)) < 9f) { return false; } if (category == "天花板" && !isCeiling) { return false; } if (category != "天花板" && isCeiling) { return false; } return true; } private static string GetCategoryForTrapId(string trapId) { string[] categoryOrder = TrapPreloader.CategoryOrder; foreach (string text in categoryOrder) { if (TrapPreloader.TrapCategories.TryGetValue(text, out var value) && value.Contains(trapId)) { return text; } } return ""; } private static void ShuffleList(IList list, Random rng) { for (int num = list.Count - 1; num > 0; num--) { int num2 = rng.Next(num + 1); int index = num; int index2 = num2; T value = list[num2]; T value2 = list[num]; list[index] = value; list[index2] = value2; } } private static double GetFrostProbability(int difficulty) { return difficulty switch { 1 => 0.1, 2 => 0.2, _ => 0.0, }; } private static void SpawnBounceObjects(Random rng, string scene) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00fc: Unknown result type (might be due to invalid IL or missing references) if (!TrapPreloader.TrapCategories.TryGetValue("跳跳乐1", out var value) || value.Count == 0) { return; } if (_cachedBounceObjects.TryGetValue(scene, out var value2)) { foreach (var item in value2) { var (pos, _) = item; ArchitectSpawn(item.Item2, pos); } return; } List list = new List(ActiveTraps); List used = new List(); List<(Vector3, string)> list2 = new List<(Vector3, string)>(); int mask = LayerMask.GetMask(new string[1] { "Terrain" }); foreach (GameObject item2 in list) { if ((Object)(object)item2 == (Object)null) { continue; } Vector3 position = item2.transform.position; bool flag = false; for (int i = 0; i < 10; i++) { if (flag) { break; } flag = TryPlaceBounceObject(position, rng, value, used, mask, 0f, 30f, list2); } for (int j = 0; j < 10; j++) { if (flag) { break; } flag = TryPlaceBounceObject(position, rng, value, used, mask, -30f, 0f, list2); } } if (list2.Count > 0) { _cachedBounceObjects[scene] = list2; } } private static bool TryPlaceBounceObject(Vector3 trapPos, Random rng, List pool, List used, int terrainMask, float angleMin, float angleMax, List<(Vector3, string)> newCache) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) float num = (float)(rng.NextDouble() * (double)(angleMax - angleMin) + (double)angleMin) * ((float)Math.PI / 180f); Vector3 val = trapPos + new Vector3(Mathf.Cos(num) * 6f, Mathf.Sin(num) * 6f, 0f); Vector2 val2 = Vector2.op_Implicit(val); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(trapPos.x, trapPos.y); Vector2 val4 = val2 - val3; RaycastHit2D val5 = Physics2D.Raycast(val3, ((Vector2)(ref val4)).normalized, ((Vector2)(ref val4)).magnitude, terrainMask); if ((Object)(object)((RaycastHit2D)(ref val5)).collider != (Object)null) { return false; } if ((Object)(object)Physics2D.OverlapCircle(val2, 0.5f, terrainMask) != (Object)null) { return false; } RaycastHit2D val6 = Physics2D.Raycast(val2 + Vector2.up * 5f, Vector2.down, 10f, terrainMask); if ((Object)(object)((RaycastHit2D)(ref val6)).collider == (Object)null) { return false; } Vector3 groundedPos = new Vector3(((RaycastHit2D)(ref val6)).point.x, ((RaycastHit2D)(ref val6)).point.y + 3f, val.z); if (IsTooCloseToPickup(groundedPos)) { return false; } if (used.Any((Vector3 p) => Vector2.Distance(Vector2.op_Implicit(p), Vector2.op_Implicit(groundedPos)) < 8f)) { return false; } string text = pool[rng.Next(pool.Count)]; ArchitectSpawn(text, groundedPos); used.Add(groundedPos); newCache.Add((groundedPos, text)); return true; } private static void SpawnPlatforms(Random rng, string scene) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: 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) if (!TrapPreloader.TrapCategories.TryGetValue("平台类1", out var value) || value.Count == 0) { return; } if (_cachedPlatforms.TryGetValue(scene, out var value2)) { foreach (var item in value2) { var (pos, _) = item; ArchitectSpawn(item.Item2, pos); } return; } List list = new List(ActiveTraps); List list2 = new List(); List<(Vector3, string)> list3 = new List<(Vector3, string)>(); int mask = LayerMask.GetMask(new string[1] { "Terrain" }); foreach (GameObject item2 in list) { if ((Object)(object)item2 == (Object)null) { continue; } Vector3 position = item2.transform.position; int num = 0; for (int i = 0; i < 2; i++) { bool flag = false; for (int j = 0; j < 15; j++) { float num2 = (float)(rng.NextDouble() * 360.0); float num3 = 6f + (float)rng.NextDouble() * 4f; float num4 = num2 * ((float)Math.PI / 180f); Vector3 targetPos = position + new Vector3(Mathf.Cos(num4) * num3, Mathf.Sin(num4) * num3, 0f); if (!((Object)(object)Physics2D.OverlapBox(Vector2.op_Implicit(targetPos), new Vector2(10f, 10f), 0f, mask) != (Object)null) && !list2.Any((Vector3 p) => Vector2.Distance(Vector2.op_Implicit(p), Vector2.op_Implicit(targetPos)) < 8f) && !IsTooCloseToPickup(targetPos)) { string text = value[rng.Next(value.Count)]; ArchitectSpawn(text, targetPos); list2.Add(targetPos); list3.Add((targetPos, text)); flag = true; num++; break; } } if (!flag) { break; } } } if (list3.Count > 0) { _cachedPlatforms[scene] = list3; } } private static void ArchitectSpawn(string id, Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: 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_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) try { TrapMeta value; TrapMeta trapMeta = (TrapPreloader.TrapMetaDict.TryGetValue(id, out value) ? value : new TrapMeta()); Vector3 val = pos; if (!trapMeta.NeedsActivator) { if (TrapPreloader.LoweredSpikeTraps.Contains(id)) { val.y -= 1.8f; } if (id == "wp_trap_spikes") { val.y += 5f; } if (TrapPreloader.LargeTraps.Contains(id)) { val.y -= 1.5f; } if (TrapPreloader.ThornTraps.Contains(id)) { val.y -= 2.5f; } } string text = null; Vector3 val2 = Vector3.zero; if (trapMeta.NeedsActivator && !string.IsNullOrEmpty(trapMeta.ActivatorId)) { if (id == "swing_trap_spike") { Vector3 val3 = _surfacePoints.OrderBy((Vector3 p) => Mathf.Abs(p.x - pos.x)).FirstOrDefault(); ((Vector3)(ref val2))..ctor(pos.x, val3.y, 0f); } else { val2 = pos + new Vector3(1.5f, 0f, 0f); } text = "Activate_" + Guid.NewGuid().ToString().Substring(0, 8); SpawnActivatorWithEvent(trapMeta.ActivatorId, val2, text); val = ((!(trapMeta.PositionOffset != Vector3.zero)) ? pos : (val2 + trapMeta.PositionOffset)); } if (!(Type.GetType("Architect.Objects.Placeable.PlaceableObject, Architect")?.GetField("RegisteredObjects", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(id)) { return; } Type type = Type.GetType("Architect.Placements.ObjectPlacement, Architect"); Type type2 = Type.GetType("Architect.Config.Types.ConfigValue, Architect"); Array array = null; Dictionary config = trapMeta.Config; if (config != null && config.Count > 0 && type2 != null) { MethodInfo methodInfo = Type.GetType("Architect.Config.ConfigurationManager, Architect")?.GetMethod("DeserializeConfigValue", BindingFlags.Static | BindingFlags.Public); if (methodInfo != null) { List list = new List(); foreach (KeyValuePair item in trapMeta.Config) { object obj = methodInfo.Invoke(null, new object[2] { item.Key, item.Value }); if (obj != null) { list.Add(obj); } } if (list.Count > 0) { array = Array.CreateInstance(type2, list.Count); for (int i = 0; i < list.Count; i++) { array.SetValue(list[i], i); } } } } if (array == null) { array = ((type2 != null) ? Array.CreateInstance(type2, 0) : Array.Empty()); } (string, string, int)[] array2 = ((text == null) ? Array.Empty<(string, string, int)>() : new(string, string, int)[1] { (text, "activate_trap", 0) }); object obj2 = Activator.CreateInstance(type, dictionary[id], val, Guid.NewGuid().ToString().Substring(0, 8), false, 0f, 1f, false, 0, Array.Empty<(string, string)>(), array2, array); object? obj3 = type.GetMethod("SpawnObject")?.Invoke(obj2, new object[5] { Vector3.zero, null, 0f, 1f, false }); GameObject val4 = (GameObject)((obj3 is GameObject) ? obj3 : null); if (Object.op_Implicit((Object)(object)val4)) { if (TrapPreloader.ThornTraps.Contains(id)) { val4.transform.rotation = Quaternion.Euler(0f, 0f, 90f); } if (trapMeta.PositionRotate != Vector3.zero) { Transform transform = val4.transform; transform.rotation *= Quaternion.Euler(trapMeta.PositionRotate); } if (TrapPreloader.LargeTraps.Contains(id)) { val4.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); } if (TrapPreloader.ThornTraps.Contains(id)) { val4.transform.localScale = new Vector3(0.5f, 1f, 0.33f); } if (TrapPreloader.TrapCategories.TryGetValue("平台类1", out var value2) && value2.Contains(id) && !TrapPreloader.SmallPlatforms.Contains(id)) { val4.transform.localScale = new Vector3(0.33f, 0.33f, 0.33f); } if (id == "abyss_tendrils") { val4.AddComponent(); } IDictionary dictionary2 = Type.GetType("Architect.Placements.PlacementManager, Architect")?.GetField("Objects", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as IDictionary; string text2 = type.GetProperty("ID")?.GetValue(obj2) as string; if (dictionary2 != null && text2 != null) { dictionary2[text2] = val4; } ActiveTraps.Add(val4); if ((Object)(object)val4 != (Object)null && _movementEnabled) { Random rng = new Random(_masterSeed ^ id.GetHashCode() ^ ((object)(Vector3)(ref pos)).GetHashCode()); TrapMovement.ApplyTrapMovement(val4, id, rng); } } } catch (Exception) { } } private static void SpawnActivatorWithEvent(string activatorId, Vector3 pos, string eventName) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) try { if (!(Type.GetType("Architect.Objects.Placeable.PlaceableObject, Architect")?.GetField("RegisteredObjects", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(activatorId)) { return; } Type type = Type.GetType("Architect.Placements.ObjectPlacement, Architect"); Type type2 = Type.GetType("Architect.Config.Types.ConfigValue, Architect"); Array array = ((type2 != null) ? Array.CreateInstance(type2, 0) : Array.Empty()); string item = ((activatorId == "trigger_zone") ? "ZoneEnter" : "OnActivate"); object obj = Activator.CreateInstance(type, dictionary[activatorId], pos, Guid.NewGuid().ToString().Substring(0, 8), false, 0f, 1f, false, 0, new(string, string)[1] { (item, eventName) }, Array.Empty<(string, string, int)>(), array); object? obj2 = type.GetMethod("SpawnObject")?.Invoke(obj, new object[5] { Vector3.zero, null, 0f, 1f, false }); GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null); if (Object.op_Implicit((Object)(object)val)) { IDictionary dictionary2 = Type.GetType("Architect.Placements.PlacementManager, Architect")?.GetField("Objects", BindingFlags.Static | BindingFlags.Public)?.GetValue(null) as IDictionary; string text = type.GetProperty("ID")?.GetValue(obj) as string; if (dictionary2 != null && text != null) { dictionary2[text] = val; } } } catch { } } } [HarmonyPatch(typeof(SavedItem), "TryGet")] public static class TryGetPatch { public static bool BypassRandom; private static bool _isProcessing; [HarmonyPrefix] private static bool Prefix(SavedItem __instance, ref bool __result) { try { if (__instance is ProxySavedItem) { return true; } if (BypassRandom) { return true; } if (!SilksongItemRandomizerAPI.IsEnabled()) { Plugin.Log.LogInfo((object)("[TryGetPatch] 物品随机总开关关闭,放行原物品: " + ((Object)__instance).name)); return true; } if (ItemRandomizer.ExcludedNames.Contains(((Object)__instance).name)) { Plugin.Log.LogInfo((object)("[TryGetPatch] 黑名单物品 " + ((Object)__instance).name + ",放行原版获得")); return true; } if (!ItemTypeRandomFilter.ShouldRandomize(__instance)) { Plugin.Log.LogInfo((object)("[TryGetPatch] 类型开关关闭,放行原物品: " + ((Object)__instance).name)); return true; } if (_isProcessing) { return true; } string name = ((Object)__instance).name; IRandomReward randomReward = ItemRandomizer.GetRandomReward(); if (randomReward == null) { Plugin.Log.LogInfo((object)("[TryGetPatch] 没有可用奖励,放行原物品 " + name)); return true; } _isProcessing = true; try { randomReward.Give(); __result = true; ItemRandomizer.AddGivenCount(randomReward.Id); ItemRandomizer.RecordMapping("item:" + name, "reward:" + randomReward.Id); RecentItemsUI.AddItem(randomReward); Plugin.Log.LogInfo((object)$"[TryGetPatch] 获得: {randomReward.DisplayName} (已获得次数: {ItemRandomizer.GetGivenCount(randomReward.Id)})"); } catch (Exception ex) { Plugin.Log.LogError((object)("[TryGetPatch] 给予奖励 " + randomReward?.Id + " 失败: " + ex.Message)); __result = false; } finally { _isProcessing = false; } return false; } catch (Exception arg) { Plugin.Log.LogError((object)$"[TryGetPatch] 异常: {arg}"); return true; } } } }