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.Cryptography; using System.Text; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using PEAKLib.Core; using PEAKLib.Items; using Peak.Afflictions; using PeakCustomItemMod.Items; using Photon.Pun; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Rendering; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PeakCustomItemMod")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PeakCustomItemMod")] [assembly: AssemblyTitle("PeakCustomItemMod")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PeakCustomItemMod { internal static class ChineseDisplayNameIntegration { private static bool _patched; public static void Apply(ManualLogSource log) { try { if (!TryApply(log)) { StartRetryer(log); log.LogInfo((object)"[中文物品名] PEAK_MENU_CN 尚未就绪,已启动延时重试挂载"); } } catch (Exception ex) { log.LogWarning((object)("[中文物品名] 挂载流程异常(不影响其它功能): " + ex.Message)); } } internal static bool TryApply(ManualLogSource log) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown if (_patched) { return true; } try { Type type = AccessTools.TypeByName("P.E.A.K_MENU.Features.ItemSpawn.ItemCatalogService"); if (type == null) { return false; } MethodInfo methodInfo = AccessTools.Method(type, "ResolveDisplayName", new Type[1] { typeof(Item) }, (Type[])null); if (methodInfo == null) { log.LogWarning((object)"[中文物品名] 未找到 ResolveDisplayName(Item),跳过"); return false; } Harmony val = new Harmony("Mr.PeakCustomItems.ChineseDisplayName"); HarmonyMethod val2 = new HarmonyMethod(typeof(ResolveDisplayNamePatch).GetMethod("Prefix")); val.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _patched = true; ForceRefreshCatalog(log); log.LogInfo((object)"[中文物品名] 已挂载:PEAK_MENU_CN 物品列表将优先显示中文"); return true; } catch (Exception ex) { log.LogWarning((object)("[中文物品名] 单次挂载尝试失败(将重试): " + ex.Message)); return false; } } private static void StartRetryer(ManualLogSource log) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown try { GameObject val = new GameObject("ChinesePatchRetryer"); Object.DontDestroyOnLoad((Object)(object)val); ChinesePatchRetryer chinesePatchRetryer = val.AddComponent(); chinesePatchRetryer.Init(log); } catch (Exception ex) { log.LogWarning((object)("[中文物品名] 启动重试器失败(将放弃中文补丁): " + ex.Message)); } } private static void ForceRefreshCatalog(ManualLogSource log) { try { Type type = AccessTools.TypeByName("P.E.A.K_MENU.Features.ItemSpawn.ItemSpawnRuntime"); if (type == null) { return; } PropertyInfo propertyInfo = AccessTools.Property(type, "Catalog"); if (propertyInfo == null || propertyInfo.GetGetMethod(nonPublic: true) == null) { return; } object value = propertyInfo.GetValue(null); if (value != null) { MethodInfo methodInfo = AccessTools.Method(value.GetType(), "ForceRefresh", (Type[])null, (Type[])null); if (!(methodInfo == null)) { methodInfo.Invoke(value, null); log.LogInfo((object)"[中文物品名] 已强制刷新物品目录"); } } } catch (Exception ex) { log.LogWarning((object)("[中文物品名] 强制刷新目录失败(可忽略): " + ex.Message)); } } internal static void ForceRefreshOnce(ManualLogSource log) { ForceRefreshCatalog(log); } } internal class ChinesePatchRetryer : MonoBehaviour { private ManualLogSource _log; private int _attempts; private const int MaxAttempts = 60; public void Init(ManualLogSource log) { _log = log; } private IEnumerator Start() { while (_attempts < 60) { _attempts++; if (ChineseDisplayNameIntegration.TryApply(_log)) { for (int i = 0; i < 10; i++) { ChineseDisplayNameIntegration.ForceRefreshOnce(_log); yield return (object)new WaitForSeconds(0.5f); } Object.Destroy((Object)(object)((Component)this).gameObject); yield break; } yield return (object)new WaitForSeconds(0.5f); } _log.LogWarning((object)"[中文物品名] 多次重试仍未找到 PEAK_MENU_CN,放弃中文补丁(不影响其它功能)"); Object.Destroy((Object)(object)((Component)this).gameObject); } } internal static class ResolveDisplayNamePatch { public static bool Prefix(Item item, ref string __result) { try { if ((Object)(object)item != (Object)null) { string name = ((Object)item).name; if (!string.IsNullOrEmpty(name) && ChineseNameMap.Map.TryGetValue(name, out string value)) { __result = value; return false; } string name2 = item.GetName(); if (!string.IsNullOrEmpty(name2) && !name2.StartsWith("LOC:", StringComparison.OrdinalIgnoreCase)) { __result = name2; return false; } } } catch (Exception ex) { ManualLogSource log = CustomItemsPlugin.Log; if (log != null) { log.LogWarning((object)("[中文物品名] 解析物品名异常: " + ex.Message)); } } return true; } } internal static class ChineseNameMap { public static readonly Dictionary Map = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "AK", "AK 突击步枪" }, { "Apple Berry Weird", "怪味苹果莓" }, { "ClimbingChalk", "攀岩粉" }, { "Cure-Some", "缓和药剂" }, { "Darkberry", "暗莓" }, { "Energy Elixir", "能量精油" }, { "Lollipop_Evil", "邪糖果" }, { "Matchbook", "火柴盒" }, { "Painkillers", "止痛药" }, { "Skyberry", "天空莓" }, { "Wand of Wind", "风之杖" }, { "Warpsketball", "传送篮球" }, { "Wonderberry", "奇幻莓" }, { "WildDogMilk", "野生狗奶" } }; } [BepInPlugin("Mr.PeakCustomItems", "刘泽铭的奇思妙想", "1.10.30")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class CustomItemsPlugin : BaseUnityPlugin { private ItemConfig _config = new ItemConfig(); private bool _registered; private bool _spawned; private float _nextCheck = 2f; internal static ManualLogSource Log { get; private set; } = null; public static ModDefinition Definition { get; private set; } = null; public static string PluginDirectory { get; private set; } = ""; private void Awake() { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Definition = ModDefinition.GetOrCreate(((BaseUnityPlugin)this).Info.Metadata); PluginDirectory = Path.GetDirectoryName(typeof(CustomItemsPlugin).Assembly.Location) ?? Paths.PluginPath; _config = ItemConfigLoader.LoadAll(PluginDirectory); if (_config.items.Length == 0) { Log.LogWarning((object)"没有找到任何物品配置,已生成示例物品(野生狗奶)"); ItemConfigLoader.WriteExampleFolder(Path.Combine(PluginDirectory, "WildDogMilk")); _config = ItemConfigLoader.LoadAll(PluginDirectory); } ManualLogSource log = Log; string pluginDirectory = PluginDirectory; ItemConfigEntry[] items = _config.items; log.LogInfo((object)$"刘泽铭的奇思妙想 已加载(DLL: {pluginDirectory},配置条目数: {((items != null) ? items.Length : 0)})"); try { GameObject val = new GameObject("PeakCustomItemEditor"); val.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val); Log.LogInfo((object)"已加载游戏内物品编辑器(按 F11 开关)"); } catch (Exception ex) { Log.LogWarning((object)("游戏内编辑器初始化失败(不影响其他功能): " + ex.Message)); } try { GameObject val2 = new GameObject("PetrifyBombManager"); val2.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val2); } catch (Exception ex2) { Log.LogWarning((object)("石化炸弹管理器初始化失败: " + ex2.Message)); } try { ChineseDisplayNameIntegration.Apply(Log); } catch (Exception ex3) { Log.LogWarning((object)("中文物品名显示集成失败(不影响其它功能): " + ex3.Message)); } } private void Update() { if (Time.unscaledTime < _nextCheck) { return; } _nextCheck = Time.unscaledTime + 2f; if (!_registered) { try { TryRegisterItems(); return; } catch (Exception arg) { Log.LogError((object)$"注册物品失败: {arg}"); return; } } if (!_spawned) { TrySpawnCustomItems(); } } private void TryRegisterItems() { if (_registered) { return; } ItemDatabase instance = SingletonAsset.Instance; if ((Object)(object)instance == (Object)null || ((DatabaseAsset)(object)instance).Objects == null || ((DatabaseAsset)(object)instance).Objects.Count == 0) { Log.LogInfo((object)"ItemDatabase 尚未就绪,等待..."); return; } int num = ConfigItemRegistry.RegisterFromConfig(_config, Definition); _registered = num > 0; Log.LogInfo((object)$"配置驱动注册完成:成功 {num} 个道具"); if (num <= 0) { return; } foreach (ItemConfigEntry registeredEntry in ConfigItemRegistry.RegisteredEntries) { bool flag = string.IsNullOrWhiteSpace(registeredEntry.texture) && string.IsNullOrWhiteSpace(registeredEntry.icon); if (registeredEntry.dumpTemplateTexture || flag) { ((MonoBehaviour)this).StartCoroutine(DumpTemplateDelayed(registeredEntry)); } } } private void TrySpawnCustomItems() { if (PhotonNetwork.IsConnected && !PhotonNetwork.IsMasterClient) { Log.LogInfo((object)"联机且非房主,不生成(等房主同步)"); _spawned = true; return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { Log.LogInfo((object)"本地角色尚未出生,等待..."); } else { SpawnCustomItems(localCharacter); } } private void SpawnCustomItems(Character player) { //IL_0075: 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_008a: 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_0094: 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) //IL_00a8: 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) List registeredEntries = ConfigItemRegistry.RegisteredEntries; int num = 0; foreach (ItemConfigEntry item in registeredEntries) { if (item.spawn) { num++; } } if (num == 0) { Log.LogInfo((object)"配置中没有需要生成的道具"); _spawned = true; return; } Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward * 2f + Vector3.up * 0.5f; int num2 = 0; foreach (ItemConfigEntry item2 in registeredEntries) { if (!item2.spawn) { continue; } float num3 = item2.spawnChance ?? 100f; if (num3 <= 0f) { continue; } if (num3 < 100f && Random.Range(0f, 100f) > num3) { Log.LogInfo((object)$"{item2.name}: 未触发生成(概率 {num3:0.#}%)"); continue; } string text = item2.runtimePrefabId; if (string.IsNullOrEmpty(text)) { text = "0_Items/" + item2.name; } if (!NetworkPrefabManager.HasNetworkPrefab(text)) { Log.LogWarning((object)("网络预制体不存在: " + text + ",跳过生成")); continue; } float num4 = ((float)num2 - (float)(num - 1) / 2f) * 1.1f; NetworkPrefabManager.SpawnNetworkPrefab(text, val + new Vector3(num4, 0f, 0f), Quaternion.identity, (byte)0, (object[])null); num2++; } _spawned = true; Log.LogInfo((object)$"已在玩家面前生成 {num2} 个自定义道具"); } private IEnumerator DumpTemplateDelayed(ItemConfigEntry entry) { if ((Object)(object)entry.templateGo == (Object)null) { Log.LogWarning((object)(entry.name + ": dumpTemplateTexture 模板引用为空,跳过")); yield break; } Texture2D src = null; Texture2D iconSrc = null; GameObject go = Object.Instantiate(entry.templateGo); if ((Object)(object)go != (Object)null) { go.SetActive(true); Log.LogInfo((object)(entry.name + ": dumpTemplateTexture 已实例化模板(" + entry.templateValue + "),轮询等待流式贴图加载...")); Item tmplItem = go.GetComponent(); for (int i = 0; i < 10; i++) { if (!((Object)(object)src == (Object)null) && !((Object)(object)iconSrc == (Object)null)) { break; } yield return (object)new WaitForSeconds(1f); if ((Object)(object)src == (Object)null) { src = ConfigItemRegistry.GrabTemplateTexture(tmplItem); } if ((Object)(object)iconSrc == (Object)null) { iconSrc = ConfigItemRegistry.GrabTemplateIcon(tmplItem); } } if ((Object)(object)src == (Object)null) { Log.LogWarning((object)(entry.name + ": dumpTemplateTexture 实例化克隆未抓到 3D 贴图")); ConfigItemRegistry.LogTextureDiag(tmplItem, entry.name); } else { Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从实例化克隆抓到 3D 贴图 {((Texture)src).width}x{((Texture)src).height}"); } if ((Object)(object)iconSrc != (Object)null) { Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从实例化克隆抓到物品栏图标 {((Texture)iconSrc).width}x{((Texture)iconSrc).height}"); } else { Log.LogWarning((object)(entry.name + ": dumpTemplateTexture 实例化克隆未抓到物品栏图标(UIData.icon 为空或尚未加载)")); } Object.Destroy((Object)(object)go); } if ((Object)(object)src == (Object)null || (Object)(object)iconSrc == (Object)null) { Log.LogInfo((object)(entry.name + ": dumpTemplateTexture 改从世界里的真实" + entry.templateValue + "抓取(请用菜单生成一个" + entry.templateValue + ",或等待其自然生成)")); for (int j = 0; j < 8; j++) { Item live = FindLiveTemplateItem(entry); if ((Object)(object)live != (Object)null) { if ((Object)(object)src == (Object)null) { src = ConfigItemRegistry.GrabTemplateTexture(live); if ((Object)(object)src != (Object)null) { Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从世界生成物抓到 3D 贴图 {((Texture)src).width}x{((Texture)src).height}"); } } if ((Object)(object)iconSrc == (Object)null) { iconSrc = ConfigItemRegistry.GrabTemplateIcon(live); if ((Object)(object)iconSrc != (Object)null) { Log.LogInfo((object)$"{entry.name}: dumpTemplateTexture 从世界生成物抓到物品栏图标 {((Texture)iconSrc).width}x{((Texture)iconSrc).height}"); } } if ((Object)(object)src != (Object)null && (Object)(object)iconSrc != (Object)null) { break; } } yield return (object)new WaitForSeconds(1f); } if ((Object)(object)src == (Object)null) { ConfigItemRegistry.LogTextureDiag(FindLiveTemplateItem(entry), entry.name); } } entry.templateTexture = src; entry.templateIconTex = iconSrc; if (entry.dumpTemplateTexture && (Object)(object)src == (Object)null && (Object)(object)iconSrc != (Object)null) { Log.LogInfo((object)(entry.name + ": 3D 贴图抓取失败(模板可能是纯色/程序化材质),用物品栏图标代替导出为模板源")); src = iconSrc; entry.templateTexture = iconSrc; } if (entry.dumpTemplateTexture) { if ((Object)(object)src != (Object)null) { ConfigItemRegistry.DumpTemplateTexture(src, entry, entry.configDir ?? PluginDirectory); } if ((Object)(object)iconSrc != (Object)null) { ConfigItemRegistry.DumpTemplateIcon(iconSrc, entry, entry.configDir ?? PluginDirectory); } } if ((Object)(object)src != (Object)null) { if ((Object)(object)entry.runtimeItem != (Object)null) { ConfigItemRegistry.ApplyTemplateTextureToItem(entry.runtimeItem, entry); } ApplyTemplateTextureToLiveInstances(entry); } if ((Object)(object)src == (Object)null && (Object)(object)iconSrc == (Object)null) { Log.LogWarning((object)(entry.name + ": 模板贴图抓取两种来源都没抓到" + entry.templateValue + "的原生贴图/图标(继承模式将缺 3D 贴图)")); } } private void ApplyTemplateTextureToLiveInstances(ItemConfigEntry entry) { if ((Object)(object)entry.templateTexture == (Object)null) { return; } try { Item[] array = Object.FindObjectsOfType(); Item[] array2 = array; foreach (Item val in array2) { if (!((Object)(object)val == (Object)null)) { GameObject gameObject = ((Component)val).gameObject; string text = ((gameObject != null) ? ((Object)gameObject).name : null) ?? ""; if (text.IndexOf(entry.name, StringComparison.OrdinalIgnoreCase) >= 0) { ConfigItemRegistry.ApplyTemplateTextureToItem(val, entry); } } } } catch (Exception ex) { Log.LogWarning((object)(entry.name + ": 套用模板贴图到场上实例失败: " + ex.Message)); } } private Item? FindLiveTemplateItem(ItemConfigEntry entry) { try { Item[] array = Object.FindObjectsOfType(); string text = (entry.templateValue ?? "").Trim(); string text2 = text.ToLowerInvariant(); Item[] array2 = array; foreach (Item val in array2) { if (!((Object)(object)val == (Object)null)) { string a = val.UIData?.itemName ?? ""; GameObject gameObject = ((Component)val).gameObject; string text3 = ((gameObject != null) ? ((Object)gameObject).name : null) ?? ""; if (string.Equals(a, text, StringComparison.OrdinalIgnoreCase) || string.Equals(text3, text, StringComparison.OrdinalIgnoreCase) || (text2.Contains("sports") && text3.IndexOf("sports", StringComparison.OrdinalIgnoreCase) >= 0)) { return val; } } } } catch (Exception ex) { Log.LogWarning((object)(entry.name + ": 查找世界里的" + entry.templateValue + "失败: " + ex.Message)); } return null; } } } namespace PeakCustomItemMod.Items { public class AllyBuffRpc : MonoBehaviour { private static readonly HashSet _explodedViewIds = new HashSet(); private const float ExplosionKnockbackMultiplier = 2f; private const float ExplosionVertKnockbackAdd = 18f; [PunRPC] public void ApplyAllyBuffs(Vector3 origin, float radius, string buffsJoined, float time) { //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_0087: Unknown result type (might be due to invalid IL or missing references) try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || localCharacter.data.dead || !(Vector3.Distance(((Component)localCharacter).transform.position, origin) <= radius)) { return; } string[] array = buffsJoined.Split(','); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text) && Enum.TryParse(text.Trim(), ignoreCase: true, out AfflictionType result)) { Affliction val = Affliction.CreateBlankAffliction(result); if (val != null) { val.totalTime = Mathf.Max(0.1f, time); localCharacter.refs.afflictions.AddAffliction(val, false); } } } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] AllyBuff RPC 处理失败: " + ex.Message)); } } public static void BroadcastExplode(Vector3 pos, int itemViewId) { //IL_0070: 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) try { GameUtils instance = GameUtils.instance; if (!((Object)(object)instance == (Object)null)) { AllyBuffRpc allyBuffRpc = ((Component)instance).gameObject.GetComponent() ?? ((Component)instance).gameObject.AddComponent(); if ((Object)(object)((MonoBehaviourPun)instance).photonView != (Object)null) { ((MonoBehaviourPun)instance).photonView.RPC("WildDogMilkExplode", (RpcTarget)0, new object[2] { pos, itemViewId }); } else { allyBuffRpc.ExplodeLocal(pos, itemViewId); } } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 野生狗奶爆炸广播失败: " + ex.Message)); } } [PunRPC] public void WildDogMilkExplode(Vector3 pos, int itemViewId) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (itemViewId < 0 || _explodedViewIds.Add(itemViewId)) { SpawnExplosion(pos); ConsumeItem(itemViewId); } } public void ExplodeLocal(Vector3 pos, int itemViewId) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SpawnExplosion(pos); ConsumeItem(itemViewId); } private void ConsumeItem(int itemViewId) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (itemViewId < 0) { return; } try { PhotonView val = PhotonView.Find(itemViewId); Item val2 = ((val != null) ? ((Component)val).GetComponent() : null); if (!((Object)(object)val2 == (Object)null)) { if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data.currentItem == (Object)(object)val2) { Player.localPlayer.EmptySlot(Character.localCharacter.refs.items.currentSelectedSlot); } val2.ClearDataFromBackpack(); if ((Object)(object)((MonoBehaviourPun)val2).photonView != (Object)null && (((MonoBehaviourPun)val2).photonView.IsMine || PhotonNetwork.IsMasterClient)) { PhotonNetwork.Destroy(((Component)val2).gameObject); } } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 野生狗奶消耗失败: " + ex.Message)); } } private void SpawnExplosion(Vector3 pos) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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) try { GameObject nativeExplosionPrefab = ConfigItemRegistry.GetNativeExplosionPrefab(); if ((Object)(object)nativeExplosionPrefab != (Object)null) { GameObject val = Object.Instantiate(nativeExplosionPrefab, pos, Quaternion.identity); AmplifyAoeKnockback(val); Object.Destroy((Object)(object)val, 4f); return; } GameObject orBuildAoeExplosionPrefab = ConfigItemRegistry.GetOrBuildAoeExplosionPrefab(); if ((Object)(object)orBuildAoeExplosionPrefab != (Object)null) { GameObject val2 = Object.Instantiate(orBuildAoeExplosionPrefab, pos, Quaternion.identity); AmplifyAoeKnockback(val2); Object.Destroy((Object)(object)val2, 2f); } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 爆炸实例化失败: " + ex.Message)); } } private static void AmplifyAoeKnockback(GameObject go) { if (!((Object)(object)go == (Object)null)) { AOE[] componentsInChildren = go.GetComponentsInChildren(); foreach (AOE val in componentsInChildren) { val.knockback *= 2f; val.additionalVerticalKnockback += 18f; } } } } public static class ConfigItemRegistry { private static readonly HashSet _dumpedTemplates = new HashSet(); private static readonly HashSet _dumpedIcons = new HashSet(); private static GameObject _nativeExplosionPrefab; private static GameObject _dynamiteExplosionPrefab; private static bool _dbSearched; private static GameObject _aoeExplosionPrefab; public static List RegisteredEntries { get; } = new List(); public static int RegisterFromConfig(ItemConfig config, ModDefinition definition) { RegisteredEntries.Clear(); int num = 0; ItemConfigEntry[] items = config.items; foreach (ItemConfigEntry itemConfigEntry in items) { if (string.IsNullOrWhiteSpace(itemConfigEntry.name)) { CustomItemsPlugin.Log.LogWarning((object)"配置里有个条目的 name 为空,已跳过"); continue; } if (string.IsNullOrWhiteSpace(itemConfigEntry.displayName)) { itemConfigEntry.displayName = itemConfigEntry.name; } try { Item val = FindTemplate(itemConfigEntry); if ((Object)(object)val == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(itemConfigEntry.name + ": 没有找到模板 (match=" + itemConfigEntry.templateMatch + ", value=" + itemConfigEntry.templateValue + "),已跳过")); } else { RegisterClone(val, itemConfigEntry, definition); RegisteredEntries.Add(itemConfigEntry); num++; } } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"{itemConfigEntry.name}: 注册失败: {arg}"); } } if (num > 0 && LootData.AllSpawnWeightData != null) { LootData.PopulateLootData(); CustomItemsPlugin.Log.LogInfo((object)"已重建 LootData 世界生成概率表,自定义物品按模板稀有度/生成池参与自然生成"); VerifyNaturalSpawn(); } if (num > 0) { EnsurePeakLibPrefabPool(); } return num; } private static void EnsurePeakLibPrefabPool() { try { MethodInfo method = typeof(NetworkPrefabManager).GetMethod("Initialize", BindingFlags.Static | BindingFlags.NonPublic); if (method == null) { CustomItemsPlugin.Log.LogWarning((object)"未找到 NetworkPrefabManager.Initialize(PEAKLib 版本不兼容?),跳过网络生成池初始化"); return; } method.Invoke(null, null); CustomItemsPlugin.Log.LogInfo((object)"Photon 网络生成池已切换为 PEAKLib CustomPrefabPool,自定义物品可正常网络生成"); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("初始化 PEAKLib 网络生成池失败(不影响注册/注入/自然生成): " + ex.Message)); } } private static Item? FindTemplate(ItemConfigEntry entry) { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Invalid comparison between Unknown and I4 //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Invalid comparison between Unknown and I4 ItemDatabase instance = SingletonAsset.Instance; if ((Object)(object)instance == (Object)null) { return null; } List list = new List(); if (instance.itemLookup != null) { list.AddRange(instance.itemLookup.Values); } if (((DatabaseAsset)(object)instance).Objects != null) { list.AddRange(((DatabaseAsset)(object)instance).Objects); } list = list.Where((Item i) => (Object)(object)i != (Object)null).Distinct().ToList(); string value = entry.templateValue?.Trim() ?? ""; switch ((entry.templateMatch ?? "").Trim().ToLowerInvariant()) { case "exact": foreach (Item item in list) { if (ItemName(item).Equals(value, StringComparison.OrdinalIgnoreCase) || ((Object)(object)((Component)item).gameObject != (Object)null && ((Object)((Component)item).gameObject).name.Equals(value, StringComparison.OrdinalIgnoreCase))) { return item; } } break; case "tag": { if (!Enum.TryParse(value, ignoreCase: true, out ItemTags result) || (int)result <= 0) { break; } foreach (Item item2 in list) { if ((item2.itemTags & result) > 0) { return item2; } } break; } default: foreach (Item item3 in list) { string text = ItemName(item3); if (text.Contains(value, StringComparison.OrdinalIgnoreCase) || ((Object)(object)((Component)item3).gameObject != (Object)null && ((Object)((Component)item3).gameObject).name.Contains(value, StringComparison.OrdinalIgnoreCase))) { return item3; } } break; } return null; } private static string ItemName(Item item) { try { if (item.UIData != null && !string.IsNullOrEmpty(item.UIData.itemName)) { return item.UIData.itemName; } } catch { } return ((Object)(object)((Component)item).gameObject != (Object)null) ? ((Object)((Component)item).gameObject).name : ""; } public static Item RegisterClone(Item template, ItemConfigEntry entry, ModDefinition definition) { //IL_0175: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00a3: 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_00ee: Invalid comparison between Unknown and I4 //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Invalid comparison between Unknown and I4 //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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) GameObject val = Object.Instantiate(((Component)template).gameObject); ((Object)val).name = entry.name; Object.DontDestroyOnLoad((Object)(object)val); Item component = val.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); throw new InvalidOperationException("模板 " + ((Object)template).name + " 上没有 Item 组件"); } if (component.UIData == null) { component.UIData = new ItemUIData(); } component.UIData.itemName = entry.displayName; RegisterNameLocalization(entry); if (entry.tags != null && entry.tags.Length != 0) { ItemTags val2 = (ItemTags)0; string[] tags = entry.tags; foreach (string value in tags) { if (Enum.TryParse(value, ignoreCase: true, out ItemTags result) && (int)result > 0) { val2 |= result; } } if ((int)val2 > 0) { component.itemTags = val2; } } ApplyLook(component, template, entry); try { if ((Object)(object)((Component)component).gameObject.GetComponent() == (Object)null) { ((Component)component).gameObject.AddComponent().entry = entry; } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 运行时贴图组件挂载失败: " + ex.Message)); } ApplyActionsAndCooking(component, entry); ApplyUses(component, entry); ApplyPetrifyBomb(component, entry); new ItemContent(component).Register(definition); ApplySpawnChance(component, template, entry); entry.runtimePrefabId = "0_Items/" + ((Object)((Component)component).gameObject).name; CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 网络预制体 = " + entry.runtimePrefabId)); InjectToItemDatabase(SingletonAsset.Instance, component, definition, entry.name); PeakMenuIntegrator.AddToVisibleItems(entry); entry.runtimeItem = component; CustomItemsPlugin.Log.LogInfo((object)$"已注册新道具: {entry.name} (显示名: {entry.displayName}, 标签: {component.itemTags}, 模板: {((Object)template).name})"); return component; } private static void InjectToItemDatabase(ItemDatabase? db, Item item, ModDefinition definition, string entryName) { if ((Object)(object)db == (Object)null || db.itemLookup == null || ((DatabaseAsset)(object)db).Objects == null) { CustomItemsPlugin.Log.LogWarning((object)(entryName + ": ItemDatabase 未就绪,跳过注入")); return; } if (db.itemLookup.ContainsValue(item) || ((DatabaseAsset)(object)db).Objects.Contains(item)) { CustomItemsPlugin.Log.LogInfo((object)(entryName + ": 已在 ItemDatabase 中,跳过注入")); return; } byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(definition.Id + ((Object)((Component)item).gameObject).name)); ushort num = BitConverter.ToUInt16(value, 0); bool flag = db.itemLookup.ContainsKey(num); while (db.itemLookup.ContainsKey(num)) { num++; } item.itemID = num; ((DatabaseAsset)(object)db).Objects.Add(item); db.itemLookup.Add(num, item); CustomItemsPlugin.Log.LogInfo((object)(flag ? $"{entryName}: 已注入 ItemDatabase(itemID={num},与原物品冲突已顺延,当前共 {((DatabaseAsset)(object)db).Objects.Count} 个物品)" : $"{entryName}: 已注入 ItemDatabase(itemID={num},当前共 {((DatabaseAsset)(object)db).Objects.Count} 个物品)")); } private static void VerifyNaturalSpawn() { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_015c: 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) if (LootData.AllSpawnWeightData == null) { CustomItemsPlugin.Log.LogWarning((object)"自然生成验证:概率表尚未构建(进入一局后首次抽物品时才构建),跳过"); return; } foreach (ItemConfigEntry registeredEntry in RegisteredEntries) { Item runtimeItem = registeredEntry.runtimeItem; if ((Object)(object)runtimeItem == (Object)null) { continue; } LootData component = ((Component)runtimeItem).GetComponent(); if ((Object)(object)component == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(registeredEntry.name + ": 无 LootData 组件 → 不参与世界自然生成(模板本身可能不进世界生成,属正常)")); continue; } List list = new List(); foreach (KeyValuePair> allSpawnWeightDatum in LootData.AllSpawnWeightData) { if (allSpawnWeightDatum.Value.TryGetValue(runtimeItem.itemID, out var value)) { list.Add($"{allSpawnWeightDatum.Key}(权重{value},占该池 {LootData.GetPercentageOdds(runtimeItem.itemID, allSpawnWeightDatum.Key):0.##}%)"); } } if (list.Count == 0) { CustomItemsPlugin.Log.LogWarning((object)$"{registeredEntry.name}: ❌ 未出现在任何生成池!(itemID={runtimeItem.itemID},稀有度={component.Rarity},spawnLocations={component.spawnLocations})——模板可能本身不参与世界生成"); } else { CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: ✅ 已确认进入世界生成表 (itemID={1},稀有度={2}) → {3}", registeredEntry.name, runtimeItem.itemID, component.Rarity, string.Join(";", list))); } try { bool flag = runtimeItem.IsValidToSpawn(); CustomItemsPlugin.Log.LogInfo((object)(flag ? (registeredEntry.name + ": IsValidToSpawn(当前环境)=True,可被世界生成器抽取") : (registeredEntry.name + ": IsValidToSpawn(当前环境)=False(如 banInSolo 单人局或运行设置禁用),进局后视设置而定"))); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(registeredEntry.name + ": IsValidToSpawn 判定失败(环境未就绪): " + ex.Message)); } } } private static void ApplySpawnChance(Item item, Item template, ItemConfigEntry entry) { //IL_005b: 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) if (entry.spawnChance.HasValue) { entry.spawnChance = Mathf.Clamp(entry.spawnChance.Value, 0f, 100f); return; } LootData val = ((Component)item).GetComponent() ?? ((Component)template).GetComponent(); if ((Object)(object)val != (Object)null && LootData.RarityWeights.TryGetValue(val.Rarity, out var value)) { entry.spawnChance = value; CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: spawnChance 未配置,沿用模板({((Object)template).name})生成概率 = {value}(稀有度 {val.Rarity})"); } else { entry.spawnChance = 100f; CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": spawnChance 未配置且模板(" + ((Object)template).name + ")无 LootData,默认 100(必出)")); } } internal static void ApplyLook(Item item, Item template, ItemConfigEntry entry) { string text = (string.IsNullOrEmpty(entry.configDir) ? CustomItemsPlugin.PluginDirectory : entry.configDir); try { entry.templateGo = ((Component)template).gameObject; } catch { } if (!string.IsNullOrWhiteSpace(entry.texture) || !string.IsNullOrWhiteSpace(entry.icon)) { ApplyLookTextures(item, entry); return; } if (item.UIData != null && template.UIData != null && (Object)(object)template.UIData.icon != (Object)null) { item.UIData.icon = template.UIData.icon; } CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 贴图 = 继承模板材质 (" + ((Object)template).name + ")")); } internal static void ApplyLookTextures(Item item, ItemConfigEntry entry) { //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) string path = (string.IsNullOrEmpty(entry.configDir) ? CustomItemsPlugin.PluginDirectory : entry.configDir); if (!string.IsNullOrWhiteSpace(entry.icon)) { string pngPath = Path.Combine(path, entry.icon); Texture2D val = TextureTools.LoadFromPng(pngPath); if ((Object)(object)val != (Object)null && item.UIData != null) { Texture2D icon = item.UIData.icon; if ((Object)(object)icon != (Object)null && ((Object)icon).name == Path.GetFileNameWithoutExtension(entry.icon)) { Object.DestroyImmediate((Object)(object)icon); } item.UIData.icon = val; } } else if (!string.IsNullOrWhiteSpace(entry.texture)) { string pngPath2 = Path.Combine(path, entry.texture); Texture2D val2 = TextureTools.LoadFromPng(pngPath2); if ((Object)(object)val2 != (Object)null && item.UIData != null) { item.UIData.icon = val2; } } if (string.IsNullOrWhiteSpace(entry.texture)) { return; } string text = Path.Combine(path, entry.texture); Texture2D val3 = TextureTools.LoadFromPng(text); if ((Object)(object)val3 == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 贴图文件不存在或无法解析 " + text + ",无法应用")); return; } Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); string[] source = new string[10] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO", "_Texture1", "_Texture2", "_BaseColorMap", "_Albedo" }; int num = 0; string text2 = null; Renderer[] array = componentsInChildren; foreach (Renderer val4 in array) { if ((Object)(object)val4 == (Object)null) { continue; } Material material = val4.material; List list = new List(); string[] texturePropertyNames = material.GetTexturePropertyNames(); string[] array2 = texturePropertyNames; foreach (string text3 in array2) { if (source.Contains(text3, StringComparer.OrdinalIgnoreCase) || (Object)(object)material.GetTexture(text3) != (Object)null) { list.Add(text3); } } if (list.Count == 0) { continue; } Texture texture = material.GetTexture(list[0]); Texture2D val5 = (Texture2D)(object)((texture is Texture2D) ? texture : null); foreach (string item2 in list) { material.SetTexture(item2, (Texture)(object)val3); } if ((Object)(object)val5 != (Object)null && (Object)(object)val5 != (Object)(object)val3 && ((Object)val5).name == Path.GetFileNameWithoutExtension(entry.texture)) { Object.DestroyImmediate((Object)(object)val5); } foreach (string item3 in list) { if (entry.textureOffset != null && entry.textureOffset.Length == 2) { material.SetTextureOffset(item3, new Vector2(entry.textureOffset[0], entry.textureOffset[1])); } if (entry.textureScale != null && entry.textureScale.Length == 2) { material.SetTextureScale(item3, new Vector2(entry.textureScale[0], entry.textureScale[1])); } } text2 = string.Join(",", list); num++; } if (num > 0) { CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 贴图 = {text},已替换 {num} 个渲染器的 {text2}"); } else { CustomItemsPlugin.Log.LogWarning((object)$"{entry.name}: 贴图 = {text} 已加载,但没有渲染器可替换(共 {componentsInChildren.Length} 个渲染器均未命中主纹理属性)"); } } internal static Texture2D? GrabTemplateTexture(Item? item) { if ((Object)(object)item == (Object)null) { return null; } Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); string[] array = new string[16] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO", "_BaseColorMap", "_AlbedoMap", "_Diffuse", "_DiffuseMap", "_ColorMap", "_MainTex_ST", "_MaskMap", "_BaseMap_ST", "_MainTex2", "_MainTex3" }; Renderer[] array2 = componentsInChildren; foreach (Renderer val in array2) { if ((Object)(object)val == (Object)null) { continue; } Material material = val.material; string[] array3 = array; foreach (string text in array3) { if (material.HasProperty(text)) { Texture texture = material.GetTexture(text); Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (val2 != null && ((Texture)val2).width > 0 && ((Texture)val2).height > 0) { return val2; } } } } return null; } internal static Texture2D? GrabTemplateIcon(Item? item) { if ((Object)(object)item == (Object)null || item.UIData == null) { return null; } Texture2D icon = item.UIData.icon; if (icon != null && ((Texture)icon).width > 0 && ((Texture)icon).height > 0) { return icon; } return null; } internal static void ApplyTemplateTextureToItem(Item item, ItemConfigEntry entry) { if ((Object)(object)item == (Object)null || entry == null || (Object)(object)entry.templateTexture == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); string[] array = new string[6] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO" }; int num = 0; Renderer[] array2 = componentsInChildren; foreach (Renderer val in array2) { if ((Object)(object)val == (Object)null) { continue; } Material material = val.material; string text = null; string[] array3 = array; foreach (string text2 in array3) { if (material.HasProperty(text2)) { text = text2; break; } } if (text != null) { material.SetTexture(text, (Texture)(object)entry.templateTexture); num++; } } if (num > 0) { CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 继承模式已把模板 3D 贴图套到 {num} 个渲染器"); } } internal static void LogTextureDiag(Item? item, string entryName) { if ((Object)(object)item == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(entryName + ": dumpTemplateTexture 诊断——物品为 null")); return; } Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); string[] array = new string[6] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO" }; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append($"{entryName}: dumpTemplateTexture 诊断——共 {componentsInChildren.Length} 个渲染器:"); Renderer[] array2 = componentsInChildren; foreach (Renderer val in array2) { if ((Object)(object)val == (Object)null) { continue; } Material material = val.material; List list = new List(); string[] array3 = array; foreach (string text in array3) { if (material.HasProperty(text)) { Texture texture = material.GetTexture(text); object obj; if (!((Object)(object)texture == (Object)null)) { Texture2D val2 = (Texture2D)(object)((texture is Texture2D) ? texture : null); obj = ((val2 != null) ? $"{((Texture)val2).width}x{((Texture)val2).height}" : ((object)texture).GetType().Name); } else { obj = "null"; } string text2 = (string)obj; list.Add(text + "=" + text2); } } string[] obj2 = new string[7] { " [", ((Object)val).name, "/", null, null, null, null }; Shader shader = material.shader; obj2[3] = ((shader != null) ? ((Object)shader).name : null); obj2[4] = ":"; obj2[5] = ((list.Count == 0) ? "无主纹理属性" : string.Join(",", list)); obj2[6] = "]"; stringBuilder.Append(string.Concat(obj2)); } CustomItemsPlugin.Log.LogWarning((object)stringBuilder.ToString()); } private static bool ReadbackToPng(Texture2D src, string outPath) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) int width = ((Texture)src).width; int height = ((Texture)src).height; RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2); Graphics.Blit((Texture)(object)src, temporary); Texture2D val = new Texture2D(width, height, (TextureFormat)5, false); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; val.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); File.WriteAllBytes(outPath, ImageConversion.EncodeToPNG(val)); Object.Destroy((Object)(object)val); return true; } internal static void DumpTemplateTexture(Texture2D src, ItemConfigEntry entry, string dir) { if ((Object)(object)src == (Object)null || string.IsNullOrWhiteSpace(dir) || _dumpedTemplates.Contains(entry.name)) { return; } try { string text = Path.Combine(dir, entry.name + "_template_source.png"); ReadbackToPng(src, text); _dumpedTemplates.Add(entry.name); CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已导出模板原生贴图 -> {text} ({((Texture)src).width}x{((Texture)src).height})"); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 导出模板贴图失败: " + ex.Message)); } } internal static void DumpTemplateIcon(Texture2D src, ItemConfigEntry entry, string dir) { if ((Object)(object)src == (Object)null || string.IsNullOrWhiteSpace(dir) || _dumpedIcons.Contains(entry.name)) { return; } try { string text = Path.Combine(dir, entry.name + "_template_icon_source.png"); ReadbackToPng(src, text); _dumpedIcons.Add(entry.name); CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已导出模板物品栏图标 -> {text} ({((Texture)src).width}x{((Texture)src).height})"); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 导出模板物品栏图标失败: " + ex.Message)); } } public static void ApplyUvToItem(Item item, ItemConfigEntry entry) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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) if ((Object)(object)item == (Object)null || string.IsNullOrWhiteSpace(entry.texture)) { return; } Vector2 val = (Vector2)((entry.textureOffset != null && entry.textureOffset.Length == 2) ? new Vector2(entry.textureOffset[0], entry.textureOffset[1]) : Vector2.zero); Vector2 val2 = (Vector2)((entry.textureScale != null && entry.textureScale.Length == 2) ? new Vector2(entry.textureScale[0], entry.textureScale[1]) : Vector2.one); string[] array = new string[6] { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "MAINTEX", "ALBEDO" }; Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); Renderer[] array2 = componentsInChildren; foreach (Renderer val3 in array2) { if ((Object)(object)val3 == (Object)null) { continue; } Material material = val3.material; string[] array3 = array; foreach (string text in array3) { if (material.HasProperty(text)) { material.SetTextureOffset(text, val); material.SetTextureScale(text, val2); break; } } } } private static void RegisterNameLocalization(ItemConfigEntry entry) { try { string text = (string.IsNullOrEmpty(entry.displayName) ? entry.name : entry.displayName); if (string.IsNullOrEmpty(text)) { return; } Dictionary> mainTable = LocalizedText.mainTable; string key = "NAME_" + text.ToUpperInvariant(); if (!mainTable.ContainsKey(key)) { int num = 15; List list = new List(num); for (int i = 0; i < num; i++) { list.Add(text); } mainTable[key] = list; mainTable["DESC_" + text.ToUpperInvariant()] = list; CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已注册名称本地化 '" + text + "'(NAME_/DESC_ key),UI 不再显示 LOC: 前缀")); } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 名称本地化注入失败(不影响注册): " + ex.Message)); } } public static void ApplyActionsAndCooking(Item item, ItemConfigEntry entry) { try { ItemCooking val = ((Component)item).GetComponent(); List removeBeh = new List(); if (entry.removeCookingBehaviors != null) { removeBeh.AddRange(entry.removeCookingBehaviors); } if (entry.cooking?.removeBehaviors != null) { removeBeh.AddRange(entry.cooking.removeBehaviors); } removeBeh = removeBeh.Where((string s) => !string.IsNullOrWhiteSpace(s)).ToList(); if (removeBeh.Count > 0) { if ((Object)(object)val == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 配置要移除烹饪行为,但模板没有 ItemCooking 组件,跳过")); } else { AdditionalCookingBehavior[] array = val.additionalCookingBehaviors.Where((AdditionalCookingBehavior b) => b != null && !removeBeh.Contains(((object)b).GetType().Name, StringComparer.OrdinalIgnoreCase)).ToArray(); int num = val.additionalCookingBehaviors.Length - array.Length; if (num > 0) { val.additionalCookingBehaviors = array; CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 已移除 {1} 个烹饪行为: {2}", entry.name, num, string.Join(",", removeBeh))); } } } if (entry.removeActions != null && entry.removeActions.Length != 0) { List want = entry.removeActions.Where((string s) => !string.IsNullOrWhiteSpace(s)).ToList(); if (want.Count > 0) { List list = (from a in ((Component)item).GetComponents() where (Object)(object)a != (Object)null && want.Contains(((object)a).GetType().Name, StringComparer.OrdinalIgnoreCase) select a).ToList(); foreach (ItemAction item3 in list) { Object.Destroy((Object)(object)item3); } if (list.Count > 0) { CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 已移除 {1} 个食用动作: {2}", entry.name, list.Count, string.Join(",", list.Select((ItemAction d) => ((object)d).GetType().Name)))); } } } if (entry.addActions != null && entry.addActions.Length != 0) { int num2 = 0; HashSet hashSet = (from a in ((Component)item).GetComponents() where (Object)(object)a != (Object)null select a).Select(ActionKey).ToHashSet(StringComparer.OrdinalIgnoreCase); ActionSpec[] addActions = entry.addActions; foreach (ActionSpec actionSpec in addActions) { if (actionSpec != null && !string.IsNullOrWhiteSpace(actionSpec.type)) { string item2 = ActionKeyFor(actionSpec); if (!hashSet.Contains(item2) && TryAddAction(((Component)item).gameObject, actionSpec)) { num2++; hashSet.Add(item2); } } } if (num2 > 0) { CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已添加 {num2} 个食用动作"); } } if (entry.cooking == null) { return; } if ((Object)(object)val == (Object)null) { val = ((Component)item).gameObject.AddComponent(); CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 模板无 ItemCooking,已自动补加并启用烹饪")); } try { FieldInfo field = ((object)val).GetType().GetField("disableCooking", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null && field.FieldType == typeof(bool) && (bool)field.GetValue(val)) { field.SetValue(val, false); } } catch { } if (entry.cooking.ignoreDefaultCook) { val.ignoreDefaultCookBehavior = true; CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已关闭默认烹饪逻辑(只保留配置的行为)")); } if (entry.cooking.wreckWhenCooked) { val.wreckWhenCooked = true; CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 烹饪即毁坏物品(wreckWhenCooked)")); } if (entry.cooking.addBehaviors == null || entry.cooking.addBehaviors.Length == 0) { return; } List list2 = new List(); CookingBehaviorSpec[] addBehaviors = entry.cooking.addBehaviors; foreach (CookingBehaviorSpec cookingBehaviorSpec in addBehaviors) { if (cookingBehaviorSpec != null && !string.IsNullOrWhiteSpace(cookingBehaviorSpec.type)) { AdditionalCookingBehavior val2 = BuildCookingBehavior(item, cookingBehaviorSpec); if (val2 != null) { val2.cookedAmountToTrigger = cookingBehaviorSpec.cookedAmountToTrigger; val2.onlyOnce = cookingBehaviorSpec.onlyOnce; list2.Add(val2); CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 已添加烹饪行为 {cookingBehaviorSpec.type}(cookedAmountToTrigger={cookingBehaviorSpec.cookedAmountToTrigger}, onlyOnce={cookingBehaviorSpec.onlyOnce})"); } } } val.additionalCookingBehaviors = list2.ToArray(); } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"{entry.name}: 应用属性配置失败: {arg}"); } } public static void ReapplyLive(ItemConfigEntry entry) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0083: 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_00cc: Invalid comparison between Unknown and I4 //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_00d5: 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_00b4: 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_00b8: 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) Item runtimeItem = entry.runtimeItem; if ((Object)(object)runtimeItem == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 克隆体尚未就绪,无法实时应用(等注册完成或重启)")); return; } try { if (runtimeItem.UIData == null) { runtimeItem.UIData = new ItemUIData(); } runtimeItem.UIData.itemName = entry.displayName; RegisterNameLocalization(entry); if (entry.tags != null && entry.tags.Length != 0) { ItemTags val = (ItemTags)0; string[] tags = entry.tags; foreach (string value in tags) { if (Enum.TryParse(value, ignoreCase: true, out ItemTags result) && (int)result > 0) { val |= result; } } if ((int)val > 0) { runtimeItem.itemTags = val; } } Item val2 = FindTemplate(entry); if ((Object)(object)val2 != (Object)null) { ApplyLook(runtimeItem, val2, entry); } else { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 找不到模板,跳过贴图实时应用")); } ApplyActionsAndCooking(runtimeItem, entry); ApplyPetrifyBomb(runtimeItem, entry); CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已实时应用配置(贴图/名称/标签/属性)")); } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"{entry.name}: 实时应用失败: {arg}"); } } private static bool TryAddAction(GameObject go, ActionSpec spec) { //IL_0149: 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_01cf: Unknown result type (might be due to invalid IL or missing references) try { string text = spec.type.Trim().ToLowerInvariant(); switch (text.StartsWith("action_") ? text.Substring("action_".Length) : text) { case "modifystatus": { Action_ModifyStatus val4 = go.AddComponent(); val4.statusType = ParseEnum(spec.statusType, (STATUSTYPE)8); val4.changeAmount = spec.changeAmount; val4.ifSkeleton = spec.ifSkeleton; SetTrigger((ItemAction)(object)val4, spec.on); return true; } case "restorehunger": { Action_RestoreHunger val5 = go.AddComponent(); val5.restorationAmount = spec.restorationAmount; SetTrigger((ItemAction)(object)val5, spec.on); return true; } case "applyaffliction": { Action_ApplyAffliction val3 = go.AddComponent(); if (Enum.TryParse(spec.affliction, ignoreCase: true, out AfflictionType result)) { val3.affliction = Affliction.CreateBlankAffliction(result); if (val3.affliction != null && spec.totalTime > 0f) { val3.affliction.totalTime = spec.totalTime; } } SetTrigger((ItemAction)(object)val3, spec.on); return true; } case "giveextrastamina": { Action_GiveExtraStamina val2 = go.AddComponent(); val2.amount = spec.amount; SetTrigger((ItemAction)(object)val2, spec.on); return true; } case "consume": { Action_Consume action2 = go.AddComponent(); SetTrigger((ItemAction)(object)action2, spec.on); return true; } case "playanimation": { Action_PlayAnimation val = go.AddComponent(); val.animationName = spec.animationName; SetTrigger((ItemAction)(object)val, spec.on); return true; } case "die": { Action_Die action = go.AddComponent(); SetTrigger((ItemAction)(object)action, spec.on); return true; } default: CustomItemsPlugin.Log.LogWarning((object)("未知食用动作类型: " + spec.type + "(可选 ModifyStatus/RestoreHunger/ApplyAffliction/GiveExtraStamina/Consume/PlayAnimation/Die)")); return false; } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("添加食用动作 " + spec.type + " 失败: " + ex.Message)); return false; } } private static void SetTrigger(ItemAction action, string on) { switch ((on ?? "").Trim().ToLowerInvariant()) { case "": break; case "pressed": action.OnPressed = true; break; case "held": action.OnHeld = true; break; case "released": action.OnReleased = true; break; case "cancelled": action.OnCancelled = true; break; case "consumed": action.OnConsumed = true; break; case "secondarypressed": action.OnSecondaryPressed = true; break; case "secondaryheld": action.OnSecondaryHeld = true; break; case "secondarycastfinished": action.OnSecondaryCastFinished = true; break; case "secondarycancelled": action.OnSecondaryCancelled = true; break; default: action.OnCastFinished = true; break; } } private static string ActionKey(ItemAction a) { //IL_0016: 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) Action_ModifyStatus val = (Action_ModifyStatus)(object)((a is Action_ModifyStatus) ? a : null); if (val != null) { return $"modifystatus|{val.statusType}"; } Action_ApplyAffliction val2 = (Action_ApplyAffliction)(object)((a is Action_ApplyAffliction) ? a : null); if (val2 != null) { Affliction affliction = val2.affliction; return $"applyaffliction|{((affliction != null) ? new AfflictionType?(affliction.GetAfflictionType()) : ((AfflictionType?)null))}"; } return ((object)a).GetType().Name; } private static string ActionKeyFor(ActionSpec s) { string text = s.type.Trim(); text = (text.StartsWith("action_", StringComparison.OrdinalIgnoreCase) ? text.Substring("action_".Length) : text); if (text.Equals("modifystatus", StringComparison.OrdinalIgnoreCase)) { return "modifystatus|" + s.statusType; } if (text.Equals("applyaffliction", StringComparison.OrdinalIgnoreCase)) { return "applyaffliction|" + s.affliction; } return "Action_" + text; } private static AdditionalCookingBehavior? BuildCookingBehavior(Item item, CookingBehaviorSpec spec) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_012e: 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_0193: 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) switch (spec.type.Trim().ToLowerInvariant()) { case "explode": { CookingBehavior_WildDogMilkExplode cookingBehavior_WildDogMilkExplode = new CookingBehavior_WildDogMilkExplode(); ((AdditionalCookingBehavior)cookingBehavior_WildDogMilkExplode).onlyOnce = true; EnsureExplosionPrefab(item, (AdditionalCookingBehavior)(object)cookingBehavior_WildDogMilkExplode); return (AdditionalCookingBehavior?)(object)cookingBehavior_WildDogMilkExplode; } case "changeafflictiontime": { Action_ApplyAffliction val = ((IEnumerable)((Component)item).GetComponents()).FirstOrDefault((Func)((Action_ApplyAffliction a) => (Object)(object)a != (Object)null)); if ((Object)(object)val == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)"烹饪行为 ChangeAfflictionTime 需要物品上有 Action_ApplyAffliction,但当前没有,已跳过"); return null; } return (AdditionalCookingBehavior?)new CookingBehavior_ChangeAfflictionTime { action = val, change = spec.change }; } case "afflictall": { if (!Enum.TryParse(spec.affliction, ignoreCase: true, out AfflictionType result2)) { CustomItemsPlugin.Log.LogWarning((object)("烹饪行为 AfflictAll 需要合法的 affliction(如 Invincibility),当前为 '" + spec.affliction + "',已跳过")); return null; } return (AdditionalCookingBehavior?)(object)new CookingBehavior_AfflictAll { afflictionType = result2, totalTime = spec.totalTime, alsoExplode = false }; } case "afflictallandexplode": { if (!Enum.TryParse(spec.affliction, ignoreCase: true, out AfflictionType result)) { CustomItemsPlugin.Log.LogWarning((object)("烹饪行为 AfflictAllAndExplode 需要合法的 affliction,当前为 '" + spec.affliction + "',已跳过")); return null; } CookingBehavior_AfflictAll cookingBehavior_AfflictAll = new CookingBehavior_AfflictAll { afflictionType = result, totalTime = spec.totalTime, alsoExplode = true }; EnsureExplosionPrefab(item, (AdditionalCookingBehavior)(object)cookingBehavior_AfflictAll); return (AdditionalCookingBehavior?)(object)cookingBehavior_AfflictAll; } default: CustomItemsPlugin.Log.LogWarning((object)("未知烹饪行为类型: " + spec.type + "(可选 Explode/ChangeAfflictionTime/AfflictAll/AfflictAllAndExplode)")); return null; } } private static void EnsureExplosionPrefab(Item item, AdditionalCookingBehavior behavior) { try { ItemCooking component = ((Component)item).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.explosionPrefab = GetOrBuildAoeExplosionPrefab(); CustomItemsPlugin.Log.LogInfo((object)(((Object)item).name + ": 已挂载自定义范围爆炸体(Injury 致死+击退+击飞,range=5)")); } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(((Object)item).name + ": 挂载爆炸体失败: " + ex.Message)); } } public static GameObject GetNativeExplosionPrefab() { if ((Object)(object)_dynamiteExplosionPrefab == (Object)null && !_dbSearched) { ItemDatabase instance = SingletonAsset.Instance; if ((Object)(object)instance != (Object)null && instance.itemLookup != null) { _dbSearched = true; _dynamiteExplosionPrefab = ResolveDynamiteExplosionPrefab(instance); if ((Object)(object)_dynamiteExplosionPrefab != (Object)null) { CustomItemsPlugin.Log.LogInfo((object)"[爆炸] 已从 ItemDatabase 锁定 Dynamite.explosionPrefab(炸药同款)"); } else { CustomItemsPlugin.Log.LogWarning((object)"[爆炸] ItemDatabase 中未找到带 Dynamite 组件的条目,回退场景扫描"); } } } if ((Object)(object)_dynamiteExplosionPrefab != (Object)null) { _nativeExplosionPrefab = _dynamiteExplosionPrefab; return _nativeExplosionPrefab; } if ((Object)(object)_nativeExplosionPrefab != (Object)null) { return _nativeExplosionPrefab; } GameObject val = null; GameObject val2 = null; GameObject val3 = null; try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter?.refs?.movement?.explosionPrefab != (Object)null) { val2 = localCharacter.refs.movement.explosionPrefab; } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 读本地角色 explosionPrefab 失败: " + ex.Message)); } if ((Object)(object)val2 == (Object)null) { try { if (Character.AllCharacters != null) { foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)allCharacter?.refs?.movement?.explosionPrefab != (Object)null) { val2 = allCharacter.refs.movement.explosionPrefab; break; } } } } catch (Exception ex2) { CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 扫描角色 explosionPrefab 失败: " + ex2.Message)); } } try { MonoBehaviour[] array = Object.FindObjectsOfType(); MonoBehaviour[] array2 = array; foreach (MonoBehaviour val4 in array2) { if ((Object)(object)val4 == (Object)null) { continue; } Type type = ((object)val4).GetType(); FieldInfo field = type.GetField("explosionPrefab", BindingFlags.Instance | BindingFlags.Public); if (!(field != null) || !(field.FieldType == typeof(GameObject))) { continue; } object? value = field.GetValue(val4); GameObject val5 = (GameObject)((value is GameObject) ? value : null); if (!((Object)(object)val5 == (Object)null)) { if ((Object)(object)val3 == (Object)null) { val3 = val5; } if ((Object)(object)val == (Object)null && (type.Name == "Dynamite" || type.FullName.EndsWith(".Dynamite", StringComparison.Ordinal))) { val = val5; } } } } catch (Exception ex3) { CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 扫描场景 explosionPrefab 失败: " + ex3.Message)); } if ((Object)(object)val != (Object)null) { _nativeExplosionPrefab = val; CustomItemsPlugin.Log.LogInfo((object)"[爆炸] 已采用场上 Dynamite.explosionPrefab(炸药同款)作为原生爆炸视觉"); } else if ((Object)(object)val2 != (Object)null) { _nativeExplosionPrefab = val2; CustomItemsPlugin.Log.LogWarning((object)"[爆炸] 场上无 Dynamite,回退用 CharacterMovement.explosionPrefab(火箭引爆款)作为爆炸视觉"); } else { if (!((Object)(object)val3 != (Object)null)) { CustomItemsPlugin.Log.LogWarning((object)"[爆炸] 未取得原生 explosionPrefab,将回退到自建爆炸体"); return null; } _nativeExplosionPrefab = val3; CustomItemsPlugin.Log.LogWarning((object)"[爆炸] 场上无 Dynamite/角色移动,回退用场景任意 explosionPrefab 作为爆炸视觉"); } return _nativeExplosionPrefab; } private static GameObject ResolveDynamiteExplosionPrefab(ItemDatabase db) { try { foreach (KeyValuePair item in db.itemLookup) { Item value = item.Value; if (!((Object)(object)value == (Object)null)) { Dynamite component = ((Component)value).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)component.explosionPrefab != (Object)null) { return component.explosionPrefab; } } } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("[爆炸] 从 ItemDatabase 解析 Dynamite 失败: " + ex.Message)); } return null; } public static GameObject GetOrBuildAoeExplosionPrefab() { if ((Object)(object)_aoeExplosionPrefab == (Object)null) { _aoeExplosionPrefab = BuildAoePrefab(); } return _aoeExplosionPrefab; } private static GameObject BuildAoePrefab() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0015: 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) GameObject val = new GameObject("WildDogMilkExplosionAOE_Fallback"); AOE val2 = val.AddComponent(); val2.mask = (LayerType)0; val2.auto = true; val2.onEnable = false; val2.range = 5f; val2.knockback = 25f; val2.additionalVerticalKnockback = 8f; val2.fallTime = 0.5f; val2.statusType = (STATUSTYPE)0; val2.statusAmount = 1.5f; val2.minFactor = 0.2f; val2.factorPow = 1f; val2.ignoreFactor = false; val2.requireLineOfSigh = false; val2.capFallDamage = true; val2.fallDamageCap = 1f; val2.fallDamageCapTime = 5f; val2.canLaunchItems = true; val2.itemKnockbackMultiplier = 1f; val2.worksOnCarriedScout = true; val2.useSingleDirection = false; val2.addtlStatus = (STATUSTYPE[])(object)new STATUSTYPE[0]; val2.addlStatusAmountOverrides = new List(); val2.illegalStatus = ""; val2.hasAffliction = false; val2.affliction = null; val.AddComponent(); return val; } private static T ParseEnum(string? value, T fallback) where T : struct { if (!string.IsNullOrWhiteSpace(value) && Enum.TryParse(value.Replace("-", "").Replace(" ", ""), ignoreCase: true, out var result)) { return result; } return fallback; } private static void ApplyPetrifyBomb(Item item, ItemConfigEntry entry) { if (entry.petrifyBomb == null) { return; } GameObject gameObject = ((Component)item).gameObject; PetrifyBombBehavior component = gameObject.GetComponent(); PetrifyBombBehavior petrifyBombBehavior = component ?? gameObject.AddComponent(); petrifyBombBehavior.spec = entry.petrifyBomb; petrifyBombBehavior.duration = entry.petrifyBomb.baseDuration; PetrifyBombBehavior.RegisterSpec(item, entry); if (entry.petrifyBomb.cookDurations != null && entry.petrifyBomb.cookDurations.Length != 0) { ItemCooking component2 = ((Component)item).GetComponent(); if ((Object)(object)component2 != (Object)null) { List list = new List(); if (component2.additionalCookingBehaviors != null) { list.AddRange(component2.additionalCookingBehaviors); } bool flag = false; foreach (AdditionalCookingBehavior item2 in list) { if (item2 is CookingBehavior_PetrifyBombDuration) { flag = true; break; } } if (!flag) { list.Add((AdditionalCookingBehavior)(object)new CookingBehavior_PetrifyBombDuration { sourceItem = item, baseDuration = entry.petrifyBomb.baseDuration, cookDurations = entry.petrifyBomb.cookDurations }); component2.additionalCookingBehaviors = list.ToArray(); } } else { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 模板没有 ItemCooking,烹饪升级将不生效(但基础石化炸弹仍可用)")); } } CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 已挂载石化炸弹(基础时长 {1}s,烹饪升级 {2})", entry.name, entry.petrifyBomb.baseDuration, string.Join("/", entry.petrifyBomb.cookDurations))); } private static void ApplyUses(Item item, ItemConfigEntry entry) { if (!entry.uses.HasValue || (Object)(object)item == (Object)null) { return; } try { OptionableIntItemData data = item.GetData((DataEntryKey)2); data.HasData = true; data.Value = entry.uses.Value; if (entry.uses.Value > 0) { item.SetUseRemainingPercentage(1f); } CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 可用次数已设为 {entry.uses.Value}"); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 设置可用次数失败: " + ex.Message)); } } } [Serializable] public class CookingBehavior_AfflictAll : AdditionalCookingBehavior { public AfflictionType afflictionType; public float totalTime; public bool alsoExplode; public bool includeBots = false; private static readonly FieldInfo? ItemCookingField = typeof(AdditionalCookingBehavior).GetField("itemCooking", BindingFlags.Instance | BindingFlags.NonPublic); protected override void TriggerBehaviour(int cookedAmount) { //IL_0139: 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_00d4: Unknown result type (might be due to invalid IL or missing references) object? obj = ItemCookingField?.GetValue(this); ItemCooking val = (ItemCooking)((obj is ItemCooking) ? obj : null); if (alsoExplode) { try { if (val != null) { val.Explode(); } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 烹饪爆炸失败: " + ex.Message)); } } int num = 0; List allCharacters = Character.AllCharacters; if (allCharacters == null) { return; } foreach (Character item in allCharacters) { if ((Object)(object)item == (Object)null || item.refs == null || (Object)(object)item.refs.afflictions == (Object)null || (!includeBots && item.isBot)) { continue; } try { Affliction val2 = Affliction.CreateBlankAffliction(afflictionType); if (val2 != null) { if (totalTime > 0f) { val2.totalTime = totalTime; } item.refs.afflictions.AddAffliction(val2, false); num++; } } catch (Exception ex2) { Debug.LogWarning((object)$"[PeakCustomItem] 给 {((Object)item).name} 添加 {afflictionType} 失败: {ex2.Message}"); } } Debug.Log((object)($"[PeakCustomItem] 烹饪全员效果: {afflictionType}({totalTime}s) 已添加给 {num} 名角色" + (alsoExplode ? "(并已爆炸)" : ""))); } } [Serializable] public class CookingBehavior_PetrifyBombDuration : AdditionalCookingBehavior { public Item? sourceItem; public float baseDuration = 10f; public float[] cookDurations = new float[3] { 20f, 30f, 35f }; private static FieldInfo? _itemCookingField; protected override void TriggerBehaviour(int cookedAmount) { Item val = ResolveItem(); if ((Object)(object)val == (Object)null) { return; } PetrifyBombBehavior component = ((Component)val).GetComponent(); if (!((Object)(object)component == (Object)null)) { float num = baseDuration; int num2 = cookedAmount - 1; if (num2 >= 0 && num2 < cookDurations.Length) { num = cookDurations[num2]; } else if (cookDurations.Length != 0) { num = cookDurations[cookDurations.Length - 1]; } component.duration = num; CustomItemsPlugin.Log.LogInfo((object)$"[PeakCustomItem] 石化炸弹烹饪升级:cookedAmount={cookedAmount} → 时长 {num}s"); } } private Item? ResolveItem() { if ((Object)(object)sourceItem != (Object)null) { return sourceItem; } try { if ((object)_itemCookingField == null) { _itemCookingField = typeof(AdditionalCookingBehavior).GetField("itemCooking", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj = _itemCookingField?.GetValue(this); return ((ItemComponent)(((obj is ItemCooking) ? obj : null)?)).item; } catch { return null; } } } public class CookingBehavior_WildDogMilkExplode : AdditionalCookingBehavior { protected override void TriggerBehaviour(int cookedAmount) { //IL_005c: 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_00d0: Unknown result type (might be due to invalid IL or missing references) try { object? obj = typeof(AdditionalCookingBehavior).GetField("itemCooking", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(this); ItemCooking val = (ItemCooking)((obj is ItemCooking) ? obj : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)((ItemComponent)val).item == (Object)null)) { Item item = ((ItemComponent)val).item; Vector3 position = ((Component)val).transform.position; int itemViewId = (((Object)(object)((MonoBehaviourPun)item).photonView != (Object)null) ? ((MonoBehaviourPun)item).photonView.ViewID : (-1)); bool flag = (Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.data.currentItem == (Object)(object)item; bool flag2 = (Object)(object)((MonoBehaviourPun)item).photonView != (Object)null && ((MonoBehaviourPun)item).photonView.AmController; if (flag || flag2) { AllyBuffRpc.BroadcastExplode(position, itemViewId); } } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 野生狗奶爆炸触发失败: " + ex.Message)); } } } public class ExplosionFlash : MonoBehaviour { public float duration = 0.55f; public float maxRadius = 5f; public Color color = new Color(1f, 0.55f, 0.15f, 0.7f); private float _t; private Transform _sphere; private MeshRenderer _r; private Light _light; private void Start() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0052: 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) GameObject val = GameObject.CreatePrimitive((PrimitiveType)0); Object.Destroy((Object)(object)val.GetComponent()); val.transform.SetParent(((Component)this).transform, false); _sphere = val.transform; _r = val.GetComponent(); try { Material val2 = new Material(Shader.Find("Sprites/Default")); val2.color = color; val2.SetInt("_Cull", 0); ((Renderer)_r).material = val2; } catch { } _light = val.AddComponent(); _light.type = (LightType)2; _light.color = new Color(1f, 0.6f, 0.3f); _light.range = maxRadius * 1.6f; _light.intensity = 7f; } private void Update() { //IL_0066: 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_0082: 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_00ad: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime; float num = Mathf.Clamp01(_t / duration); if ((Object)(object)_r != (Object)null && (Object)(object)_sphere != (Object)null) { float num2 = Mathf.Lerp(0.6f, maxRadius * 2f, num); _sphere.localScale = Vector3.one * num2; Color val = ((Renderer)_r).material.color; val.a = color.a * (1f - num); ((Renderer)_r).material.color = val; } if ((Object)(object)_light != (Object)null) { _light.intensity = 7f * (1f - num); } if (_t >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } [Serializable] public class ItemConfigEntry { public string name = ""; public string displayName = ""; public string templateMatch = "contains"; public string templateValue = "milk"; public string[] tags = Array.Empty(); public string texture = ""; public string icon = ""; public float[]? textureOffset = null; public float[]? textureScale = null; public string behavior = ""; public string[] removeActions = Array.Empty(); public ActionSpec[] addActions = Array.Empty(); public string[] removeCookingBehaviors = Array.Empty(); public CookingSpec? cooking = null; public bool spawn = true; public int? uses = null; public float? spawnChance = null; public bool dumpTemplateTexture = false; [JsonIgnore] internal GameObject? templateGo = null; [JsonIgnore] internal Texture2D? templateTexture = null; [JsonIgnore] internal Texture2D? templateIconTex = null; public PetrifyBombSpec? petrifyBomb = null; [JsonIgnore] public string configDir = ""; [JsonIgnore] public string runtimePrefabId = ""; [JsonIgnore] public Item runtimeItem = null; } [Serializable] public class PetrifyBombSpec { public float baseDuration = 10f; public string[]? buffAfflictions = null; public float[] cookDurations = new float[3] { 20f, 30f, 35f }; public float rampCapDuringCountdown = 95f; public bool petrifyAtEnd = true; public float allyRadius = 0f; } [Serializable] public class ItemConfig { public ItemConfigEntry[] items = Array.Empty(); public bool liveReloadTexture = true; } [Serializable] public class ActionSpec { public string type = ""; public string on = "CastFinished"; public string statusType = ""; public float changeAmount = 0f; public bool ifSkeleton = false; public float restorationAmount = 0f; public string affliction = ""; public float totalTime = 0f; public float amount = 0f; public string animationName = ""; } [Serializable] public class CookingBehaviorSpec { public string type = ""; public int cookedAmountToTrigger = 1; public bool onlyOnce = true; public bool dontRunIfOutOfFuel = false; public string actionType = "Action_ApplyAffliction"; public float change = 0f; public string affliction = ""; public float totalTime = 0f; } [Serializable] public class CookingSpec { public bool ignoreDefaultCook = false; public bool wreckWhenCooked = false; public string[] removeBehaviors = Array.Empty(); public CookingBehaviorSpec[] addBehaviors = Array.Empty(); } public static class ItemConfigLoader { public static ItemConfig? Load(string path) { try { if (!File.Exists(path)) { return null; } string text = File.ReadAllText(path); if (string.IsNullOrWhiteSpace(text)) { return null; } ItemConfig itemConfig = JsonConvert.DeserializeObject(text); if (itemConfig == null || itemConfig.items == null) { return null; } return itemConfig; } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"读取物品配置失败 {path}: {arg}"); return null; } } public static ItemConfig LoadAll(string rootDir) { List list = new List(); string path = Path.Combine(rootDir, "itemconfig.json"); if (File.Exists(path)) { ItemConfig itemConfig = Load(path); if (itemConfig != null) { list.AddRange(itemConfig.items); } } try { string[] directories = Directory.GetDirectories(rootDir); foreach (string text in directories) { string path2 = Path.Combine(text, "itemconfig.json"); if (!File.Exists(path2)) { continue; } ItemConfig itemConfig2 = Load(path2); if (itemConfig2 == null || itemConfig2.items == null || itemConfig2.items.Length == 0) { continue; } ItemConfigEntry[] items = itemConfig2.items; foreach (ItemConfigEntry itemConfigEntry in items) { itemConfigEntry.configDir = text; if (string.IsNullOrWhiteSpace(itemConfigEntry.name)) { itemConfigEntry.name = Path.GetFileName(text); } } list.AddRange(itemConfig2.items); } } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"扫描物品文件夹失败 {rootDir}: {arg}"); } return new ItemConfig { items = list.ToArray() }; } public static void WriteEntryToFolder(string dir, ItemConfigEntry entry) { try { Directory.CreateDirectory(dir); ItemConfig itemConfig = new ItemConfig(); itemConfig.items = new ItemConfigEntry[1] { entry }; ItemConfig itemConfig2 = itemConfig; string text = JsonConvert.SerializeObject((object)itemConfig2, (Formatting)1); string text2 = "// ============================================================\n// 新物品配置(由游戏内 F10 物品编辑器生成)\n" + $"// 模板: {entry.templateValue} 生成时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}\n" + "// 修改后重启游戏生效;贴图 PNG 放到本文件夹\n// ============================================================\n"; File.WriteAllText(Path.Combine(dir, "itemconfig.json"), text2 + text); CustomItemsPlugin.Log.LogInfo((object)("已写入配置: " + Path.Combine(dir, "itemconfig.json"))); } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"写入配置失败 {dir}: {arg}"); } } public static void WriteExampleFolder(string dir) { try { Directory.CreateDirectory(dir); File.WriteAllText(Path.Combine(dir, "itemconfig.json"), "{\n // ============================================================\n // 示例物品:野生狗奶(以游戏内\"奶白金\"为模板)\n // 用法:改 name/displayName → 重启游戏 → 进一局看到道具\n // texture/icon 留空 = 完全继承模板外观\n // spawnChance 留空(null) = 沿用模板生成概率;写 0~100 可覆盖\n // 属性(v1.4.6 全部可选,不写 = 继承模板):\n // removeActions: 移除模板继承的食用动作,如 [\"Action_ApplyAffliction\"]\n // addActions: 添加食用动作,如 [{ \"type\": \"ModifyStatus\", \"on\": \"CastFinished\",\n // \"statusType\": \"Hot\", \"changeAmount\": -0.5 }]\n // type 可选 ModifyStatus/RestoreHunger/ApplyAffliction/\n // GiveExtraStamina/Consume/PlayAnimation\n // on 可选 Pressed/Held/Released/CastFinished/Cancelled/Consumed/Secondary*\n // removeCookingBehaviors: 移除烹饪行为,如 [\"CookingBehavior_ChangeAfflictionTime\"]\n // cooking: 烹饪配置,如 { \"ignoreDefaultCook\": true, \"addBehaviors\": [\n // { \"type\": \"Explode\" },\n // { \"type\": \"AfflictAllAndExplode\", \"affliction\": \"Invincibility\", \"totalTime\": 10 } ] }\n // addBehaviors type 可选 Explode/ChangeAfflictionTime/AfflictAll/AfflictAllAndExplode\n // 石化炸弹(v1.6.0):加 \"petrifyBomb\": { \"baseDuration\": 10, \"cookDurations\": [20,30,35],\n // \"petrifyAtEnd\": true, \"explodeAtEnd\": true, \"splashRadius\": 6, \"splashPetrify\": 50 }\n // → 食用 10s 无敌+逐渐石化,结束满石化(变石头)+爆炸波及附近;烹饪逐次升级时长\n // ItemInfoDisplay 兼容(v1.6.3):addActions 挂标准动作即可显示属性(像官方物品):\n // ApplyAffliction→获得无敌 / RestoreHunger→恢复饱食 / ModifyStatus→状态增减\n // 技巧:on 留空 \"\" = 纯装饰组件(不触发不生效,仅让属性面板显示,如石化)\n // ============================================================\n \"items\": [\n {\n \"name\": \"WildDogMilk\",\n \"displayName\": \"野生狗奶\",\n \"templateMatch\": \"contains\",\n \"templateValue\": \"milk\",\n \"tags\": [],\n \"texture\": \"\",\n \"icon\": \"\",\n \"behavior\": \"\",\n \"spawn\": true,\n \"spawnChance\": null\n }\n ]\n}"); CustomItemsPlugin.Log.LogInfo((object)("已生成示例物品文件夹: " + dir)); } catch (Exception arg) { CustomItemsPlugin.Log.LogError((object)$"生成示例配置失败 {dir}: {arg}"); } } } public class ItemEditorUI : MonoBehaviour { private static class PreviewRig { private const int Layer = 30; private static GameObject? _root; private static Camera? _cam; private static RenderTexture? _rt; private static int _lastItemId = -1; private static GameObject? _clone; private static Vector3 _center = Vector3.zero; private static float _radius = 2f; private static float _yaw = 0f; private static float _pitch = 12f; public static RenderTexture? RT => _rt; public static bool HasModel => (Object)(object)_clone != (Object)null; private static void EnsureBuilt() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_00b4: 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_0122: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_018b: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown if (!((Object)(object)_root != (Object)null)) { _root = new GameObject("PeakPreviewStage"); _root.layer = 30; _root.transform.position = new Vector3(0f, -10000f, 0f); Object.DontDestroyOnLoad((Object)(object)_root); GameObject val = new GameObject("PeakPreviewCam"); val.transform.SetParent(_root.transform, false); _cam = val.AddComponent(); _cam.clearFlags = (CameraClearFlags)2; _cam.backgroundColor = new Color(0.14f, 0.14f, 0.17f, 1f); _cam.cullingMask = 1073741824; _cam.orthographic = false; _cam.nearClipPlane = 0.01f; _cam.farClipPlane = 100f; _cam.fieldOfView = 35f; ((Behaviour)_cam).enabled = false; GameObject val2 = new GameObject("PeakPreviewKey"); val2.transform.SetParent(_root.transform, false); Light val3 = val2.AddComponent(); val3.type = (LightType)1; val3.intensity = 1.3f; val3.color = Color.white; val2.transform.rotation = Quaternion.Euler(40f, 35f, 0f); GameObject val4 = new GameObject("PeakPreviewFill"); val4.transform.SetParent(_root.transform, false); Light val5 = val4.AddComponent(); val5.type = (LightType)1; val5.intensity = 0.55f; val5.color = Color.white; val4.transform.rotation = Quaternion.Euler(-25f, -130f, 0f); _rt = new RenderTexture(512, 512, 24, (RenderTextureFormat)0); _rt.Create(); _cam.targetTexture = _rt; } } public static void SetItem(Item item) { //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_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_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) EnsureBuilt(); int num = (((Object)(object)item != (Object)null) ? ((Object)item).GetInstanceID() : (-1)); if (num == _lastItemId) { return; } _lastItemId = num; for (int num2 = _root.transform.childCount - 1; num2 >= 0; num2--) { Transform child = _root.transform.GetChild(num2); bool flag; switch (((Object)child).name) { case "PeakPreviewCam": case "PeakPreviewKey": case "PeakPreviewFill": flag = true; break; default: flag = false; break; } if (!flag) { Object.Destroy((Object)(object)((Component)child).gameObject); } } _clone = null; if ((Object)(object)item == (Object)null) { return; } _clone = CloneVisual(((Component)item).transform, _root.transform); Bounds val = default(Bounds); bool flag2 = false; Renderer[] componentsInChildren = _clone.GetComponentsInChildren(true); foreach (Renderer val2 in componentsInChildren) { if (!flag2) { val = val2.bounds; flag2 = true; } else { ((Bounds)(ref val)).Encapsulate(val2.bounds); } } if (flag2) { Vector3 size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude > 1E-06f) { _center = ((Bounds)(ref val)).center; float num3 = Mathf.Max(new float[3] { ((Bounds)(ref val)).size.x, ((Bounds)(ref val)).size.y, ((Bounds)(ref val)).size.z }); _radius = num3 * 1.1f + 0.3f; goto IL_01f0; } } _center = _clone.transform.position; _radius = 2f; goto IL_01f0; IL_01f0: _yaw = 0f; _pitch = 12f; } public static void Orbit(float dx, float dy) { _yaw += dx * 0.4f; _pitch = Mathf.Clamp(_pitch + dy * 0.4f, -80f, 80f); } private static GameObject CloneVisual(Transform src, Transform parent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0022: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Expected O, but got Unknown GameObject val = new GameObject(((Object)src).name); val.transform.SetParent(parent, false); val.transform.localPosition = src.localPosition; val.transform.localRotation = src.localRotation; val.transform.localScale = src.localScale; val.layer = 30; MeshFilter component = ((Component)src).GetComponent(); MeshRenderer component2 = ((Component)src).GetComponent(); if ((Object)(object)component2 != (Object)null) { MeshFilter val2 = val.AddComponent(); val2.sharedMesh = (((Object)(object)component != (Object)null) ? component.sharedMesh : null); MeshRenderer val3 = val.AddComponent(); ((Renderer)val3).sharedMaterial = ((Renderer)component2).material; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; ((Renderer)val3).lightProbeUsage = (LightProbeUsage)0; } else { SkinnedMeshRenderer component3 = ((Component)src).GetComponent(); if ((Object)(object)component3 != (Object)null) { MeshFilter val4 = val.AddComponent(); val4.sharedMesh = component3.sharedMesh; MeshRenderer val5 = val.AddComponent(); ((Renderer)val5).sharedMaterial = ((Renderer)component3).material; ((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val5).receiveShadows = false; ((Renderer)val5).lightProbeUsage = (LightProbeUsage)0; } } foreach (Transform item in src) { Transform src2 = item; CloneVisual(src2, val.transform); } return val; } public static void Render() { //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_0069: 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_0083: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_cam == (Object)null)) { float num = _pitch * (MathF.PI / 180f); float num2 = _yaw * (MathF.PI / 180f); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Cos(num) * Mathf.Sin(num2), Mathf.Sin(num), Mathf.Cos(num) * Mathf.Cos(num2)); ((Component)_cam).transform.position = _center + val * _radius; ((Component)_cam).transform.LookAt(_center); _cam.Render(); } } } private bool _show; private int _sel = -1; private Vector2 _scroll; private Vector2 _jsonScroll; private string _status = "按 F11 打开/关闭编辑器"; private string _json = ""; private static List? _blockedActions; private Texture2D? _prevTex; private string _prevPath = ""; private int _uvMode = 0; private string _bx = "0"; private string _by = "0"; private string _bsx = "1"; private string _bsy = "1"; private List RegisteredEntries => ConfigItemRegistry.RegisteredEntries; private void Update() { if (Input.GetKeyDown((KeyCode)292)) { _show = !_show; if (_show) { ClampSelection(); if (_sel >= 0) { LoadJson(RegisteredEntries[_sel]); } _status = "编辑器已打开(F11 关闭)"; } RefreshInputBlock(); } else { RefreshInputBlock(); } if (_show && _sel >= 0 && _sel < RegisteredEntries.Count) { ItemConfigEntry itemConfigEntry = RegisteredEntries[_sel]; if ((Object)(object)itemConfigEntry.runtimeItem != (Object)null) { PreviewRig.SetItem(itemConfigEntry.runtimeItem); } PreviewRig.Render(); HandleUvKeys(itemConfigEntry); } } private void RefreshInputBlock() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 if (_show) { SetInputBlocked(block: true); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; return; } SetInputBlocked(block: false); if ((int)Cursor.lockState != 1) { Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } } private static void SetInputBlocked(bool block) { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.input == (Object)null) { return; } Type type = ((object)localCharacter.input).GetType(); if (block) { if (_blockedActions != null) { return; } _blockedActions = new List(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (typeof(InputAction).IsAssignableFrom(fieldInfo.FieldType)) { object? value = fieldInfo.GetValue(localCharacter.input); InputAction val = (InputAction)((value is InputAction) ? value : null); if (val != null) { val.Disable(); _blockedActions.Add(val); } } } } else { if (_blockedActions == null) { return; } foreach (InputAction blockedAction in _blockedActions) { if (blockedAction != null) { blockedAction.Enable(); } } _blockedActions = null; } } private void ClampSelection() { if (_sel < 0 || _sel >= RegisteredEntries.Count) { _sel = ((RegisteredEntries.Count <= 0) ? (-1) : 0); } } private void LoadJson(ItemConfigEntry e) { try { _json = JsonConvert.SerializeObject((object)e, (Formatting)1); } catch { _json = "{}"; } } private void OnGUI() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_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_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: 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) if (!_show) { return; } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; GUILayout.BeginArea(new Rect(20f, 20f, (float)(Screen.width - 40), (float)(Screen.height - 40)), GUI.skin.box); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("刘泽铭的奇思妙想 编辑器 [F11] 关闭", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUILayout.EndHorizontal(); if (RegisteredEntries.Count == 0) { GUILayout.Label("(暂无已注册物品,等游戏加载完物品数据库后会自动出现)", Array.Empty()); GUILayout.EndArea(); return; } GUILayout.BeginHorizontal(Array.Empty()); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(220f), GUILayout.MaxHeight((float)(Screen.height - 120)) }); _scroll = GUILayout.BeginScrollView(_scroll, Array.Empty()); ClampSelection(); for (int i = 0; i < RegisteredEntries.Count; i++) { ItemConfigEntry itemConfigEntry = RegisteredEntries[i]; if (GUILayout.Button(itemConfigEntry.displayName + "\n(" + itemConfigEntry.name + ")", Array.Empty())) { _sel = i; LoadJson(itemConfigEntry); } } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); _jsonScroll = GUILayout.BeginScrollView(_jsonScroll, Array.Empty()); if (_sel >= 0 && _sel < RegisteredEntries.Count) { DrawEditor(RegisteredEntries[_sel]); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUILayout.EndHorizontal(); GUILayout.Label(_status, Array.Empty()); GUILayout.EndArea(); } private void DrawEditor(ItemConfigEntry e) { //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("名称与外观", GUI.skin.box, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("显示名", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); e.displayName = GUILayout.TextField(e.displayName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (GUILayout.Button("应用", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { ApplyAndStatus(e, "显示名已更新(实时)", liveOnly: true); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("标签(csv)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); string text = ((e.tags != null) ? string.Join(",", e.tags) : ""); string text2 = GUILayout.TextField(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); if (GUILayout.Button("应用", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(60f) })) { e.tags = (from s in text2.Split(',') select s.Trim() into s where s.Length > 0 select s).ToArray(); ApplyAndStatus(e, "标签已更新(实时)", liveOnly: true); } GUILayout.EndHorizontal(); GUILayout.Space(6f); GUILayout.Label("贴图", GUI.skin.box, Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("文件", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); e.texture = GUILayout.TextField(e.texture, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(200f) }); GUILayout.EndHorizontal(); if (!string.IsNullOrEmpty(e.configDir) && Directory.Exists(e.configDir)) { string[] array = Directory.GetFiles(e.configDir, "*.png").Select(Path.GetFileName).ToArray(); if (array.Length != 0) { GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("当前文件夹:", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }); GUILayout.EndHorizontal(); string[] array2 = array; foreach (string text3 in array2) { if (GUILayout.Button(text3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(220f) })) { e.texture = text3; } } } } EnsureVec2(ref e.textureOffset); EnsureVec2(ref e.textureScale); string nameOfFocusedControl = GUI.GetNameOfFocusedControl(); if (nameOfFocusedControl != "uv_offx" && nameOfFocusedControl != "uv_offy" && nameOfFocusedControl != "uv_scx" && nameOfFocusedControl != "uv_scy") { SyncUvBuffers(e); } GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty()); _uvMode = GUILayout.SelectionGrid(_uvMode, new string[2] { "3D 模型预览", "2D 取景板" }, 2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(260f) }); GUILayout.EndHorizontal(); Rect rect = GUILayoutUtility.GetRect(300f, 300f); if (_uvMode == 0) { DrawPreview(rect, e); } else { DrawUvPad(rect, e); } GUILayout.Label((_uvMode == 0) ? "3D 预览:左键拖=移动贴图,滚轮=缩放,右键拖=旋转模型;直接看模型上真实落点(所见即所得)" : "2D 取景:左键拖=移动,滚轮=整体缩放,Shift+左键=单轴缩放", Array.Empty()); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("偏移X", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }); GUI.SetNextControlName("uv_offx"); _bx = GUILayout.TextField(_bx, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); GUILayout.Label("偏移Y", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }); GUI.SetNextControlName("uv_offy"); _by = GUILayout.TextField(_by, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("缩放X", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }); GUI.SetNextControlName("uv_scx"); _bsx = GUILayout.TextField(_bsx, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); GUILayout.Label("缩放Y", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }); GUI.SetNextControlName("uv_scy"); _bsy = GUILayout.TextField(_bsy, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) }); if (GUILayout.Button("应用数值", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) }) && TryParseUv(e)) { ApplyUvLive(e); _status = "✅ UV 数值已应用(实时)"; } GUILayout.EndHorizontal(); GUILayout.Label("键盘微调:方向键=移动(Shift 微调) | - 与 = 键=整体缩放 | 预览上拖拽更直观", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(380f) }); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"UV 偏移 X:{e.textureOffset[0]:0.00}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); float num2 = GUILayout.HorizontalSlider(e.textureOffset[0], -2f, 2f, Array.Empty()); if (Math.Abs(num2 - e.textureOffset[0]) > 0.0001f) { e.textureOffset[0] = num2; ApplyUvLive(e); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"UV 偏移 Y:{e.textureOffset[1]:0.00}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); float num3 = GUILayout.HorizontalSlider(e.textureOffset[1], -2f, 2f, Array.Empty()); if (Math.Abs(num3 - e.textureOffset[1]) > 0.0001f) { e.textureOffset[1] = num3; ApplyUvLive(e); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"UV 缩放 X:{e.textureScale[0]:0.00}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); float num4 = GUILayout.HorizontalSlider(e.textureScale[0], -3f, 3f, Array.Empty()); if (Math.Abs(num4 - e.textureScale[0]) > 0.0001f) { e.textureScale[0] = num4; ApplyUvLive(e); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label($"UV 缩放 Y:{e.textureScale[1]:0.00}", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); float num5 = GUILayout.HorizontalSlider(e.textureScale[1], -3f, 3f, Array.Empty()); if (Math.Abs(num5 - e.textureScale[1]) > 0.0001f) { e.textureScale[1] = num5; ApplyUvLive(e); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("应用贴图", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) })) { ApplyAndStatus(e, "贴图已更新(实时,场上物品同步)", liveOnly: true); } if (GUILayout.Button("复位 UV(偏移0 缩放1)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) })) { e.textureOffset[0] = 0f; e.textureOffset[1] = 0f; e.textureScale[0] = 1f; e.textureScale[1] = 1f; ApplyAndStatus(e, "UV 已复位(实时)", liveOnly: true); SyncUvBuffers(e); } GUILayout.EndHorizontal(); GUILayout.Label("缩放<1 放大贴图 / >1 缩小;负数=翻转", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(210f) }); GUILayout.Space(6f); GUILayout.Label("属性(高级:直接改 JSON,[应用并保存] 实时生效并写盘)", GUI.skin.box, Array.Empty()); _json = GUILayout.TextArea(_json, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Height(220f), GUILayout.ExpandWidth(true) }); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("应用并保存", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { ApplyJsonAndSave(e); } if (GUILayout.Button("重置为条目", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) })) { LoadJson(e); } GUILayout.EndHorizontal(); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("保存配置到文件", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(160f) })) { SaveEntry(e); } GUILayout.EndHorizontal(); GUILayout.Label("提示:显示名/标签/贴图/动作/烹饪/UV 实时生效;name/模板/生成概率 改完需重启游戏生效。", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); } private void DrawPreview(Rect pr, ItemConfigEntry e) { //IL_0001: 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_00a4: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Invalid comparison between Unknown and I4 //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Invalid comparison between Unknown and I4 //IL_0147: 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_014e: 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_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Invalid comparison between Unknown and I4 //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) GUI.Box(pr, GUIContent.none); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref pr)).x + 2f, ((Rect)(ref pr)).y + 2f, ((Rect)(ref pr)).width - 4f, ((Rect)(ref pr)).height - 4f); if ((Object)(object)e.runtimeItem == (Object)null) { GUI.Label(val, "等待物品生成(进一局后自动可用)"); return; } RenderTexture rT = PreviewRig.RT; if ((Object)(object)rT != (Object)null) { GUI.DrawTexture(val, (Texture)(object)rT, (ScaleMode)2); } GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).yMax - 18f, ((Rect)(ref val)).width, 18f), $"偏移({e.textureOffset[0]:0.00},{e.textureOffset[1]:0.00}) 缩放({e.textureScale[0]:0.00},{e.textureScale[1]:0.00}) | 右键拖拽=旋转模型"); if (!((Rect)(ref pr)).Contains(Event.current.mousePosition)) { return; } if ((int)Event.current.type == 3 && Event.current.button == 1) { Vector2 delta = Event.current.delta; PreviewRig.Orbit(delta.x, delta.y); Event.current.Use(); } else if ((int)Event.current.type == 3 && Event.current.button == 0 && !Event.current.shift) { Vector2 delta2 = Event.current.delta; e.textureOffset[0] = Mathf.Clamp(e.textureOffset[0] + delta2.x * 0.005f, -5f, 5f); e.textureOffset[1] = Mathf.Clamp(e.textureOffset[1] - delta2.y * 0.005f, -5f, 5f); ApplyUvLive(e); _status = "UV 已实时应用(3D 预览拖拽)"; Event.current.Use(); } else if ((int)Event.current.type == 6) { float num = 1f - Event.current.delta.y * 0.1f; if (num <= 0f) { num = 0.9f; } e.textureScale[0] = Mathf.Clamp(e.textureScale[0] * num, 0.05f, 20f); e.textureScale[1] = Mathf.Clamp(e.textureScale[1] * num, 0.05f, 20f); ApplyUvLive(e); _status = "UV 缩放已实时应用(3D 预览滚轮,上=放大贴图)"; Event.current.Use(); } } private void HandleUvKeys(ItemConfigEntry e) { EnsureVec2(ref e.textureOffset); EnsureVec2(ref e.textureScale); bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); float num = (flag ? 0.005f : 0.02f); bool flag2 = false; if (Input.GetKey((KeyCode)276)) { e.textureOffset[0] -= num; flag2 = true; } if (Input.GetKey((KeyCode)275)) { e.textureOffset[0] += num; flag2 = true; } if (Input.GetKey((KeyCode)273)) { e.textureOffset[1] += num; flag2 = true; } if (Input.GetKey((KeyCode)274)) { e.textureOffset[1] -= num; flag2 = true; } float num2 = (flag ? 0.01f : 0.03f); if (Input.GetKey((KeyCode)45) || Input.GetKey((KeyCode)269)) { ScaleMul(e, 1f - num2); flag2 = true; } if (Input.GetKey((KeyCode)61) || Input.GetKey((KeyCode)43) || Input.GetKey((KeyCode)270)) { ScaleMul(e, 1f + num2); flag2 = true; } if (flag2) { ClampUv(e); ApplyUvLive(e); _status = "UV 已键盘微调(实时)"; } } private static void ScaleMul(ItemConfigEntry e, float k) { e.textureScale[0] = Mathf.Clamp(e.textureScale[0] * k, 0.05f, 20f); e.textureScale[1] = Mathf.Clamp(e.textureScale[1] * k, 0.05f, 20f); } private static void ClampUv(ItemConfigEntry e) { e.textureOffset[0] = Mathf.Clamp(e.textureOffset[0], -5f, 5f); e.textureOffset[1] = Mathf.Clamp(e.textureOffset[1], -5f, 5f); e.textureScale[0] = Mathf.Clamp(e.textureScale[0], -20f, 20f); e.textureScale[1] = Mathf.Clamp(e.textureScale[1], -20f, 20f); } private void SyncUvBuffers(ItemConfigEntry e) { _bx = e.textureOffset[0].ToString("0.00"); _by = e.textureOffset[1].ToString("0.00"); _bsx = e.textureScale[0].ToString("0.00"); _bsy = e.textureScale[1].ToString("0.00"); } private bool TryParseUv(ItemConfigEntry e) { if (!float.TryParse(_bx, out var result) || !float.TryParse(_by, out var result2) || !float.TryParse(_bsx, out var result3) || !float.TryParse(_bsy, out var result4)) { _status = "❌ UV 数值格式错误(请输入数字)"; return false; } e.textureOffset[0] = result; e.textureOffset[1] = result2; e.textureScale[0] = result3; e.textureScale[1] = result4; ClampUv(e); return true; } private void DrawUvPad(Rect pad, ItemConfigEntry e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0226: 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) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: 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_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Invalid comparison between Unknown and I4 //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0511: Invalid comparison between Unknown and I4 //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04c3: Unknown result type (might be due to invalid IL or missing references) //IL_0431: Unknown result type (might be due to invalid IL or missing references) //IL_0464: Unknown result type (might be due to invalid IL or missing references) GUI.Box(pad, GUIContent.none); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref pad)).x + 4f, ((Rect)(ref pad)).y + 4f, ((Rect)(ref pad)).width - 8f, ((Rect)(ref pad)).height - 8f); Texture2D val2 = LoadPreviewTexture(e); if ((Object)(object)val2 == (Object)null) { GUI.Label(val, "无自定义贴图(texture 留空继承模板,无法预览)\n先把 texture 填上 PNG 文件名"); return; } GUI.DrawTexture(val, (Texture)(object)val2, (ScaleMode)2); float num = e.textureOffset[0]; float num2 = e.textureOffset[1]; float num3 = e.textureScale[0]; float num4 = e.textureScale[1]; float num5 = (0f - num) / num3; float num6 = (0f - num2) / num4; float num7 = num5 + 1f / num3; float num8 = num6 + 1f / num4; float num9 = Mathf.Clamp01(num5); float num10 = Mathf.Clamp01(num6); float num11 = Mathf.Clamp01(num7); float num12 = Mathf.Clamp01(num8); Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(((Rect)(ref val)).x + num9 * ((Rect)(ref val)).width, ((Rect)(ref val)).y + (1f - num12) * ((Rect)(ref val)).height, (num11 - num9) * ((Rect)(ref val)).width, (num12 - num10) * ((Rect)(ref val)).height); Color color = default(Color); ((Color)(ref color))..ctor(0f, 0f, 0f, 0.6f); GUI.color = color; if (((Rect)(ref val3)).y > ((Rect)(ref val)).y) { GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, ((Rect)(ref val3)).y - ((Rect)(ref val)).y), (Texture)(object)Texture2D.whiteTexture); } if (((Rect)(ref val3)).yMax < ((Rect)(ref val)).yMax) { GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val3)).yMax, ((Rect)(ref val)).width, ((Rect)(ref val)).yMax - ((Rect)(ref val3)).yMax), (Texture)(object)Texture2D.whiteTexture); } if (((Rect)(ref val3)).x > ((Rect)(ref val)).x) { GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val3)).y, ((Rect)(ref val3)).x - ((Rect)(ref val)).x, ((Rect)(ref val3)).height), (Texture)(object)Texture2D.whiteTexture); } if (((Rect)(ref val3)).xMax < ((Rect)(ref val)).xMax) { GUI.DrawTexture(new Rect(((Rect)(ref val3)).xMax, ((Rect)(ref val3)).y, ((Rect)(ref val)).xMax - ((Rect)(ref val3)).xMax, ((Rect)(ref val3)).height), (Texture)(object)Texture2D.whiteTexture); } GUI.color = Color.white; GUI.color = Color.yellow; GUI.DrawTexture(new Rect(((Rect)(ref val3)).x, ((Rect)(ref val3)).y, ((Rect)(ref val3)).width, 2f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref val3)).x, ((Rect)(ref val3)).yMax - 2f, ((Rect)(ref val3)).width, 2f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref val3)).x, ((Rect)(ref val3)).y, 2f, ((Rect)(ref val3)).height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref val3)).xMax - 2f, ((Rect)(ref val3)).y, 2f, ((Rect)(ref val3)).height), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).yMax - 18f, ((Rect)(ref val)).width, 18f), $"偏移({num:0.00},{num2:0.00}) 缩放({num3:0.00},{num4:0.00})"); if (!((Rect)(ref pad)).Contains(Event.current.mousePosition)) { return; } bool shift = Event.current.shift; if ((int)Event.current.type == 3 && Event.current.button == 0) { Vector2 delta = Event.current.delta; if (shift) { e.textureScale[0] = Mathf.Clamp(e.textureScale[0] * (1f + delta.x * 0.05f), -10f, 10f); e.textureScale[1] = Mathf.Clamp(e.textureScale[1] * (1f + delta.y * 0.05f), -10f, 10f); } else { e.textureOffset[0] = Mathf.Clamp(e.textureOffset[0] + delta.x * 0.005f, -2f, 2f); e.textureOffset[1] = Mathf.Clamp(e.textureOffset[1] - delta.y * 0.005f, -2f, 2f); } ApplyUvLive(e); _status = "UV 已实时应用(场上物品同步)"; Event.current.Use(); } else if ((int)Event.current.type == 6) { float num13 = 1f - Event.current.delta.y * 0.1f; if (num13 <= 0f) { num13 = 0.9f; } e.textureScale[0] = Mathf.Clamp(e.textureScale[0] * num13, 0.05f, 20f); e.textureScale[1] = Mathf.Clamp(e.textureScale[1] * num13, 0.05f, 20f); ApplyUvLive(e); _status = "UV 缩放已实时应用(滚轮,上=放大贴图)"; Event.current.Use(); } } private void ApplyUvLive(ItemConfigEntry e) { if ((Object)(object)e.runtimeItem != (Object)null) { ConfigItemRegistry.ApplyUvToItem(e.runtimeItem, e); } LoadJson(e); } private Texture2D? LoadPreviewTexture(ItemConfigEntry e) { if (string.IsNullOrWhiteSpace(e.texture)) { return null; } string path = (string.IsNullOrEmpty(e.configDir) ? CustomItemsPlugin.PluginDirectory : e.configDir); string text = Path.Combine(path, e.texture); if (text == _prevPath && (Object)(object)_prevTex != (Object)null) { return _prevTex; } _prevTex = TextureTools.LoadFromPng(text); _prevPath = text; return _prevTex; } private void EnsureVec2(ref float[]? v) { if (v == null || v.Length != 2) { v = new float[2]; } } private void ApplyAndStatus(ItemConfigEntry e, string msg, bool liveOnly) { try { ConfigItemRegistry.ReapplyLive(e); _status = "✅ " + e.name + ": " + msg; } catch (Exception ex) { _status = "❌ " + e.name + ": 应用失败 " + ex.Message; } } private void ApplyJsonAndSave(ItemConfigEntry e) { try { ItemConfigEntry itemConfigEntry = JsonConvert.DeserializeObject(_json); if (itemConfigEntry == null) { _status = "❌ JSON 解析失败(空)"; return; } e.displayName = itemConfigEntry.displayName; e.templateMatch = itemConfigEntry.templateMatch; e.templateValue = itemConfigEntry.templateValue; e.tags = itemConfigEntry.tags ?? Array.Empty(); e.texture = itemConfigEntry.texture; e.icon = itemConfigEntry.icon; e.textureOffset = itemConfigEntry.textureOffset; e.textureScale = itemConfigEntry.textureScale; e.behavior = itemConfigEntry.behavior; e.removeActions = itemConfigEntry.removeActions ?? Array.Empty(); e.addActions = itemConfigEntry.addActions ?? Array.Empty(); e.removeCookingBehaviors = itemConfigEntry.removeCookingBehaviors ?? Array.Empty(); e.cooking = itemConfigEntry.cooking; e.petrifyBomb = itemConfigEntry.petrifyBomb; e.spawn = itemConfigEntry.spawn; e.spawnChance = itemConfigEntry.spawnChance; ConfigItemRegistry.ReapplyLive(e); ItemConfigLoader.WriteEntryToFolder(e.configDir, e); _status = "✅ " + e.name + ": 已从 JSON 应用并保存到 " + e.configDir + "/itemconfig.json"; } catch (Exception ex) { _status = "❌ JSON 应用失败: " + ex.Message; } } private void SaveEntry(ItemConfigEntry e) { try { ItemConfigLoader.WriteEntryToFolder(e.configDir, e); _status = "✅ 已保存: " + e.configDir + "/itemconfig.json(重启后结构性字段才生效)"; } catch (Exception ex) { _status = "❌ 保存失败: " + ex.Message; } } } internal static class PeakMenuIntegrator { private const string CfgFileName = "ruangfafa.peakmenu.cfg"; private const string MenuPluginDir = "RuangfafaPersonalTeam-PEAK_MENU_CN"; private const string MenuDllName = "ruangfafa.peakmenu.dll"; private static bool? _installed; internal static bool IsPeakMenuInstalled() { if (_installed.HasValue) { return _installed.Value; } try { string path = Path.Combine(Paths.PluginPath, "RuangfafaPersonalTeam-PEAK_MENU_CN", "ruangfafa.peakmenu.dll"); _installed = File.Exists(path); if (!_installed.Value) { _installed = Directory.Exists(Paths.PluginPath) && Directory.EnumerateFiles(Paths.PluginPath, "ruangfafa.peakmenu.dll", SearchOption.AllDirectories).Any(); } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("PEAK_MENU_CN 检测失败(视为未安装): " + ex.Message)); _installed = false; } return _installed.Value; } internal static void AddToVisibleItems(ItemConfigEntry entry) { if (!IsPeakMenuInstalled()) { return; } try { string path = Path.Combine(Paths.ConfigPath, "ruangfafa.peakmenu.cfg"); if (!File.Exists(path)) { CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": PEAK_MENU_CN 已安装但配置尚未生成,跳过自动加入(下次启动再补)")); return; } string text = "Mr.PeakCustomItems:" + entry.name; byte[] bytes = File.ReadAllBytes(path); string text2 = Encoding.UTF8.GetString(bytes); int num = text2.IndexOf("VisibleItems", StringComparison.OrdinalIgnoreCase); if (num < 0) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 未在 ruangfafa.peakmenu.cfg 中找到 VisibleItems 配置,跳过")); return; } int num2 = text2.IndexOfAny(new char[2] { '\r', '\n' }, num); if (num2 < 0) { num2 = text2.Length; } if (text2.IndexOf(text, num, num2 - num, StringComparison.Ordinal) >= 0) { CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已在 PEAK_MENU_CN 生成列表中,跳过")); return; } int num3 = text2.IndexOf('=', num); bool flag = num3 >= 0 && num3 < num2 && string.IsNullOrWhiteSpace(text2.Substring(num3 + 1, num2 - num3 - 1)); string s = text2.Substring(0, num2) + (flag ? "" : "|") + text + text2.Substring(num2); File.WriteAllBytes(path, Encoding.UTF8.GetBytes(s)); CustomItemsPlugin.Log.LogInfo((object)(entry.name + ": 已自动加入 PEAK_MENU_CN 生成主列表(ruangfafa.peakmenu.cfg → VisibleItems)")); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 写入 PEAK_MENU_CN 配置失败(不影响本模组运行): " + ex.Message)); } } } public class PetrifyBombBehavior : MonoBehaviour { public float duration = 10f; public PetrifyBombSpec spec = null; public static readonly Dictionary SpecsByKey = new Dictionary(); private Item? _item; private bool _started; private void Awake() { _item = ((Component)this).GetComponent(); if (!((Object)(object)_item == (Object)null)) { Item? item = _item; item.OnPrimaryFinishedCast = (Action)Delegate.Combine(item.OnPrimaryFinishedCast, new Action(OnConsumed)); Item? item2 = _item; item2.OnConsumed = (Action)Delegate.Combine(item2.OnConsumed, new Action(OnConsumed)); } } private void OnDestroy() { if (!((Object)(object)_item == (Object)null)) { Item? item = _item; item.OnPrimaryFinishedCast = (Action)Delegate.Remove(item.OnPrimaryFinishedCast, new Action(OnConsumed)); Item? item2 = _item; item2.OnConsumed = (Action)Delegate.Remove(item2.OnConsumed, new Action(OnConsumed)); } } public static void RegisterSpec(Item item, ItemConfigEntry entry) { if (!((Object)(object)item == (Object)null) && entry?.petrifyBomb != null) { string name = ((Object)((Component)item).gameObject).name; SpecsByKey[name] = entry.petrifyBomb; if (!string.IsNullOrEmpty(entry.displayName)) { SpecsByKey[entry.displayName] = entry.petrifyBomb; } } } private void OnConsumed() { if (_started) { return; } _started = true; string text = (((Object)(object)_item != (Object)null && _item.UIData != null) ? _item.UIData.itemName : ((Object)this).name); PetrifyBombSpec petrifyBombSpec = spec ?? ResolveSpecFromRegistry(); if (petrifyBombSpec == null) { CustomItemsPlugin.Log.LogWarning((object)(text + ": 石化炸弹配置为空(组件字段 + 注册表都未命中)。请确认 itemconfig.json 写了 petrifyBomb 且重启过游戏")); return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { CustomItemsPlugin.Log.LogWarning((object)(text + ": 食用触发时找不到本机角色,已跳过")); return; } PetrifyBombManager.StartBomb(localCharacter, duration, petrifyBombSpec); CustomItemsPlugin.Log.LogInfo((object)string.Format("{0}: 食用触发石化炸弹(时长 {1}s,烹饪升级 {2})", text, duration, string.Join("/", petrifyBombSpec.cookDurations))); } private PetrifyBombSpec? ResolveSpecFromRegistry() { if ((Object)(object)_item != (Object)null) { if (SpecsByKey.TryGetValue(((Object)((Component)_item).gameObject).name, out PetrifyBombSpec value) && value != null) { return value; } if (_item.UIData != null && !string.IsNullOrEmpty(_item.UIData.itemName) && SpecsByKey.TryGetValue(_item.UIData.itemName, out PetrifyBombSpec value2) && value2 != null) { return value2; } } return null; } } public class PetrifyBombManager : MonoBehaviour { private class BombState { public Character? ch; public float duration; public PetrifyBombSpec? spec; public float deathTime; public bool finished; } public static PetrifyBombManager? Instance; private static AllyBuffRpc _rpc; private static readonly Dictionary _activeBombs = new Dictionary(); private static GameObject _cachedLoopPrefab; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } } public static void StartBomb(Character ch, float duration, PetrifyBombSpec spec) { if (!((Object)(object)Instance == (Object)null) && !((Object)(object)ch == (Object)null) && spec != null) { int instanceID = ((Object)ch).GetInstanceID(); PruneDead(); if (_activeBombs.TryGetValue(instanceID, out BombState value) && value != null && (Object)(object)value.ch != (Object)null && !value.ch.data.dead && (value.deathTime > Time.time || value.finished)) { float num = Mathf.Max(0f, value.deathTime - Time.time); CustomItemsPlugin.Log.LogInfo((object)$"[PeakCustomItem] {((Object)ch).name}:已有生效中的野生狗奶倒计时(距满石化致死约 {num:F0}s)或已满石化待死,本次饮用忽略,不覆盖致死"); return; } _activeBombs[instanceID] = new BombState { ch = ch, duration = duration, spec = spec, deathTime = Time.time + duration }; ((MonoBehaviour)Instance).StartCoroutine(Instance.BombRoutine(_activeBombs[instanceID])); } } private static void PruneDead() { if (_activeBombs.Count == 0) { return; } List list = new List(); foreach (KeyValuePair activeBomb in _activeBombs) { BombState value = activeBomb.Value; if (value == null || (Object)(object)value.ch == (Object)null || (Object)(object)value.ch.data == (Object)null || value.ch.data.dead) { list.Add(activeBomb.Key); } else if (!value.finished && value.deathTime <= Time.time) { list.Add(activeBomb.Key); } } foreach (int item in list) { _activeBombs.Remove(item); } } private static void EnsureRpc() { if ((Object)(object)_rpc != (Object)null) { return; } try { GameUtils instance = GameUtils.instance; GameObject val = ((instance != null) ? ((Component)instance).gameObject : null); if ((Object)(object)val != (Object)null) { _rpc = val.GetComponent() ?? val.AddComponent(); } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] AllyBuff RPC 组件挂载失败(半径增益将仅本地生效): " + ex.Message)); } } private static void BroadcastAllyBuff(Character ch, float radius, string[] buffs, float time) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) EnsureRpc(); if ((Object)(object)_rpc == (Object)null || (Object)(object)GameUtils.instance == (Object)null) { return; } try { string text = string.Join(",", buffs); ((MonoBehaviourPun)GameUtils.instance).photonView.RPC("ApplyAllyBuffs", (RpcTarget)0, new object[4] { ((Component)ch).transform.position, radius, text, Mathf.Max(0.1f, time) }); } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 半径增益 RPC 发送失败: " + ex.Message)); } } private IEnumerator BombRoutine(BombState state) { Character ch = state.ch; float duration = state.duration; PetrifyBombSpec spec = state.spec; if ((Object)(object)ch == (Object)null || ch.data.dead) { int badId = (((Object)(object)ch != (Object)null) ? ((Object)ch).GetInstanceID() : (-1)); _activeBombs.Remove(badId); yield break; } bool hasAlly = spec.allyRadius > 0f; string[] buffs = spec.buffAfflictions; if (buffs == null || buffs.Length == 0) { buffs = new string[1] { "Invincibility" }; } if (hasAlly) { ApplyRadiateSphere(ch, spec.allyRadius, duration); } ApplyBuffsToSelf(ch, buffs, duration); if (hasAlly) { BroadcastAllyBuff(ch, spec.allyRadius, buffs, duration); } float t = 0f; float tick = 0f; while (t < duration && (Object)(object)ch != (Object)null && !ch.data.dead) { t += Time.deltaTime; tick += Time.deltaTime; float p = Mathf.Clamp01(t / duration); ch.data.SetPetrify((int)(ushort)Mathf.FloorToInt(p * spec.rampCapDuringCountdown)); if (hasAlly && tick >= 0.5f) { tick = 0f; BroadcastAllyBuff(ch, spec.allyRadius, buffs, Mathf.Max(0.5f, duration - t)); } yield return null; } int id = (((Object)(object)ch != (Object)null) ? ((Object)ch).GetInstanceID() : (-1)); if ((Object)(object)ch == (Object)null || ch.data.dead) { _activeBombs.Remove(id); } else if (spec.petrifyAtEnd) { List endTargets = new List { ch }; if (hasAlly) { Vector3 origin = ((Component)ch).transform.position; foreach (Character other in Character.AllCharacters) { if (!((Object)(object)other == (Object)null) && !((Object)(object)other == (Object)(object)ch) && !other.data.dead && Vector3.Distance(((Component)other).transform.position, origin) <= spec.allyRadius) { endTargets.Add(other); } } } foreach (Character target in endTargets) { if ((Object)(object)target != (Object)null && !target.data.dead) { target.data.SetPetrify(100); } } CustomItemsPlugin.Log.LogInfo((object)$"[PeakCustomItem] 满石化致死:本人 + 半径内 {endTargets.Count - 1} 名友军(跟随半径团灭)"); if (_activeBombs.TryGetValue(id, out BombState st) && st != null) { st.finished = true; } } else { _activeBombs.Remove(id); } } private static void ApplyBuffsToSelf(Character ch, string[] buffs, float time) { //IL_00a0: 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) if ((Object)(object)ch == (Object)null || ch.data.dead) { return; } foreach (string text in buffs) { if (string.IsNullOrWhiteSpace(text) || !Enum.TryParse(text.Trim(), ignoreCase: true, out AfflictionType result)) { continue; } try { Affliction val = Affliction.CreateBlankAffliction(result); if (val != null) { val.totalTime = Mathf.Max(0.1f, time); ch.refs.afflictions.AddAffliction(val, false); } } catch (Exception ex) { Debug.LogWarning((object)$"[PeakCustomItem] 前置 buff {result} 施加失败: {ex.Message}"); } } } private static void ApplyRadiateSphere(Character ch, float radius, float duration) { if ((Object)(object)ch == (Object)null || ch.data.dead) { return; } try { Affliction val = Affliction.CreateBlankAffliction((AfflictionType)24); if (val != null) { val.totalTime = Mathf.Max(0.1f, duration); FieldInfo field = ((object)val).GetType().GetField("radius", BindingFlags.Instance | BindingFlags.Public); if (field != null) { field.SetValue(val, radius); } ch.refs.afflictions.AddAffliction(val, false); CustomItemsPlugin.Log.LogInfo((object)$"[PeakCustomItem] 已施加 RadiateInfiniteStam(半径 {radius}m)→ 原生 InfiniteStamSphere 球体生成(与童军野心同款)"); } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 原生 InfiniteStamSphere 球体施加失败(本次无球体特效): " + ex.Message)); } } private static GameObject MakeRadiusVisual(Character ch, float radius) { //IL_00c6: 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) GameObject val = null; GameObject val2 = FindAmuletLoopPrefab(); if ((Object)(object)val2 != (Object)null) { try { val = Object.Instantiate(val2); ((Object)val).name = "WildDogMilkAuraLoop"; val.SetActive(true); CustomItemsPlugin.Log.LogInfo((object)"[PeakCustomItem] 已克隆护符 amuletLoop(自然尺寸,与童军野心 1:1)"); } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 克隆 amuletLoop 失败,回退手搓球: " + ex.Message)); val = null; } } if ((Object)(object)val == (Object)null) { val = MakeRadiusSphere(radius); } if ((Object)(object)val != (Object)null && (Object)(object)ch != (Object)null && (Object)(object)((Component)ch).transform != (Object)null) { val.transform.SetParent(((Component)ch).transform, false); val.transform.localPosition = new Vector3(0f, 1f, 0f); val.transform.localRotation = Quaternion.identity; } return val; } private static GameObject FindAmuletLoopPrefab() { if ((Object)(object)_cachedLoopPrefab != (Object)null) { return _cachedLoopPrefab; } try { ItemDatabase instance = SingletonAsset.Instance; if (instance?.itemLookup == null) { return null; } Type typeFromHandle = typeof(GameObject); BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy; foreach (Item value in instance.itemLookup.Values) { if (!((Object)(object)value == (Object)null) && !((Object)(object)((Component)value).gameObject == (Object)null) && ((Object)((Component)value).gameObject).name.IndexOf("infinitestam", StringComparison.OrdinalIgnoreCase) >= 0) { GameObject val = ResolveAmuletLoop(((Component)value).gameObject, typeFromHandle, flags); if ((Object)(object)val != (Object)null) { _cachedLoopPrefab = val; CustomItemsPlugin.Log.LogInfo((object)("[PeakCustomItem] 已定位护符 amuletLoop(童军野心 " + ((Object)value).name + ")")); return _cachedLoopPrefab; } } } foreach (Item value2 in instance.itemLookup.Values) { if (!((Object)(object)value2 == (Object)null) && !((Object)(object)((Component)value2).gameObject == (Object)null)) { GameObject val2 = ResolveAmuletLoop(((Component)value2).gameObject, typeFromHandle, flags); if ((Object)(object)val2 != (Object)null) { _cachedLoopPrefab = val2; CustomItemsPlugin.Log.LogInfo((object)("[PeakCustomItem] 已定位护符 amuletLoop(来自 " + ((Object)value2).name + ")")); return _cachedLoopPrefab; } } } foreach (Item value3 in instance.itemLookup.Values) { if (!((Object)(object)value3 == (Object)null) && !((Object)(object)((Component)value3).gameObject == (Object)null)) { Transform val3 = FindChildByName(((Component)value3).gameObject.transform, "amuletLoop"); if ((Object)(object)val3 != (Object)null) { _cachedLoopPrefab = ((Component)val3).gameObject; CustomItemsPlugin.Log.LogInfo((object)("[PeakCustomItem] 已按名字定位护符 amuletLoop(来自 " + ((Object)value3).name + ")")); return _cachedLoopPrefab; } } } } catch (Exception ex) { Debug.LogWarning((object)("[PeakCustomItem] 查找 amuletLoop 失败(改用回退球): " + ex.Message)); } return _cachedLoopPrefab; } private static GameObject ResolveAmuletLoop(GameObject root, Type goType, BindingFlags flags) { if ((Object)(object)root == (Object)null) { return null; } Component[] components = root.GetComponents(); foreach (Component val in components) { if ((Object)(object)val == (Object)null) { continue; } FieldInfo field = ((object)val).GetType().GetField("amuletLoop", flags); if (field != null && field.FieldType == goType) { object? value = field.GetValue(val); GameObject val2 = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val2 != (Object)null) { return val2; } } } Transform val3 = FindChildByName(root.transform, "amuletLoop"); return ((Object)(object)val3 != (Object)null) ? ((Component)val3).gameObject : null; } private static Transform FindChildByName(Transform root, string name) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if ((Object)(object)root == (Object)null) { return null; } if (string.Equals(((Object)root).name, name, StringComparison.OrdinalIgnoreCase)) { return root; } foreach (Transform item in root) { Transform root2 = item; Transform val = FindChildByName(root2, name); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static float MeasureDiameter(GameObject go) { //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) //IL_004c: 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_005b: 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_006f: 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_0095: 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_00b3: 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_00bc: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return 0f; } MeshFilter component = go.GetComponent(); Bounds bounds; if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { bounds = component.sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; return Mathf.Max(new float[3] { size.x, size.y, size.z }); } Renderer component2 = go.GetComponent(); if ((Object)(object)component2 != (Object)null) { bounds = component2.bounds; if (((Bounds)(ref bounds)).size != Vector3.zero) { bounds = component2.bounds; Vector3 size2 = ((Bounds)(ref bounds)).size; return Mathf.Max(new float[3] { size2.x, size2.y, size2.z }); } } return 0f; } private static GameObject MakeRadiusSphere(float radius) { //IL_009d: 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_0044: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)0); Object.Destroy((Object)(object)val.GetComponent()); ((Object)val).name = "WildDogMilkAuraSphere"; Renderer component = val.GetComponent(); if ((Object)(object)component != (Object)null) { try { Material val2 = new Material(Shader.Find("Sprites/Default")); val2.color = new Color(1f, 0.84f, 0f, 0.22f); val2.SetInt("_Cull", 0); component.material = val2; } catch (Exception) { } } val.transform.localScale = new Vector3(radius * 2f, radius * 2f, radius * 2f); return val; } } public class RuntimeLookApplier : MonoBehaviour { public ItemConfigEntry entry; private static readonly Dictionary _texCache = new Dictionary(); private bool _applied; private static readonly float[] _reapplyDelays = new float[5] { 0.5f, 1.5f, 3f, 4.5f, 6f }; private void Start() { if (_applied) { return; } _applied = true; try { Item component = ((Component)this).GetComponent(); if (!((Object)(object)component == (Object)null)) { Apply(component); ((MonoBehaviour)this).StartCoroutine(ReapplyForWindow(component)); } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("[PeakCustomItem] RuntimeLookApplier 失败: " + ex.Message)); } } private IEnumerator ReapplyForWindow(Item item) { float[] reapplyDelays = _reapplyDelays; foreach (float d in reapplyDelays) { yield return (object)new WaitForSeconds(d); try { if ((Object)(object)item != (Object)null) { Apply(item); } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("[PeakCustomItem] RuntimeLookApplier 延迟重贴失败: " + ex.Message)); } } } private void Apply(Item item) { //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_0516: Unknown result type (might be due to invalid IL or missing references) if (entry == null) { return; } string path = (string.IsNullOrEmpty(entry.configDir) ? CustomItemsPlugin.PluginDirectory : entry.configDir); if (entry.uses.HasValue) { try { OptionableIntItemData data = item.GetData((DataEntryKey)2); data.HasData = true; data.Value = entry.uses.Value; if (entry.uses.Value > 0) { item.SetUseRemainingPercentage(1f); } } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": 实例设置可用次数失败: " + ex.Message)); } } string text = ((!string.IsNullOrWhiteSpace(entry.icon)) ? entry.icon : entry.texture); if (!string.IsNullOrWhiteSpace(text) && item.UIData != null) { Texture2D val = LoadCached(Path.Combine(path, text)); if ((Object)(object)val != (Object)null) { item.UIData.icon = val; } } Texture2D val2 = null; if (!string.IsNullOrWhiteSpace(entry.texture)) { val2 = LoadCached(Path.Combine(path, entry.texture)); } else if ((Object)(object)entry.templateTexture != (Object)null) { val2 = entry.templateTexture; } if ((Object)(object)val2 == (Object)null) { return; } HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase) { "_MainTex", "_BaseMap", "_BaseTexture", "_MainTexture", "ALBEDO", "MAINTEX", "_BaseColorMap", "_Albedo" }; Renderer[] componentsInChildren = ((Component)item).GetComponentsInChildren(true); int num = 0; StringBuilder stringBuilder = new StringBuilder(); Renderer[] array = componentsInChildren; foreach (Renderer val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } SpriteRenderer val4 = (SpriteRenderer)(object)((val3 is SpriteRenderer) ? val3 : null); if (val4 != null) { try { Sprite sprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)); val4.sprite = sprite; num++; stringBuilder.Append(" [SpriteRenderer<-sprite]"); } catch (Exception ex2) { CustomItemsPlugin.Log.LogWarning((object)(entry.name + ": Sprite 替换失败 " + ex2.Message)); } continue; } Material material = val3.material; List list = new List(material.GetTexturePropertyNames()); if (list == null || list.Count == 0) { string[] obj = new string[5] { " ", ((object)val3).GetType().Name, "(shader=", null, null }; Shader shader = material.shader; obj[3] = ((shader != null) ? ((Object)shader).name : null); obj[4] = ":)"; stringBuilder.Append(string.Concat(obj)); continue; } HashSet hashSet2 = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string item2 in list) { if (hashSet.Contains(item2)) { hashSet2.Add(item2); } } foreach (string item3 in list) { if ((Object)(object)material.GetTexture(item3) != (Object)null) { hashSet2.Add(item3); } } if (hashSet2.Count == 0) { foreach (string item4 in list) { hashSet2.Add(item4); } } foreach (string item5 in hashSet2) { material.SetTexture(item5, (Texture)(object)val2); if (entry.textureOffset != null && entry.textureOffset.Length == 2) { material.SetTextureOffset(item5, new Vector2(entry.textureOffset[0], entry.textureOffset[1])); } if (entry.textureScale != null && entry.textureScale.Length == 2) { material.SetTextureScale(item5, new Vector2(entry.textureScale[0], entry.textureScale[1])); } } num++; string[] obj2 = new string[7] { " ", ((object)val3).GetType().Name, "(shader=", null, null, null, null }; Shader shader2 = material.shader; obj2[3] = ((shader2 != null) ? ((Object)shader2).name : null); obj2[4] = ":"; obj2[5] = string.Join("|", hashSet2); obj2[6] = ")"; stringBuilder.Append(string.Concat(obj2)); } if (num > 0) { CustomItemsPlugin.Log.LogInfo((object)$"{entry.name}: 实例已应用 3D 贴图,替换 {num} 个渲染器:{stringBuilder}"); } else { CustomItemsPlugin.Log.LogWarning((object)$"{entry.name}: 未找到任何可替换的 3D 贴图属性(各渲染器/属性如下){stringBuilder} —— 若场上仍看不到自定义贴图,请把这段日志发我"); } } private static Texture2D? LoadCached(string path) { if (_texCache.TryGetValue(path, out Texture2D value) && (Object)(object)value != (Object)null) { return value; } Texture2D val = TextureTools.LoadFromPng(path); if ((Object)(object)val != (Object)null) { _texCache[path] = val; } return val; } } public static class TextureTools { public static Texture2D? LoadFromPng(string pngPath) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!File.Exists(pngPath)) { return null; } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (ImageConversion.LoadImage(val, File.ReadAllBytes(pngPath))) { ((Object)val).name = Path.GetFileNameWithoutExtension(pngPath); ((Texture)val).wrapMode = (TextureWrapMode)0; ((Texture)val).filterMode = (FilterMode)1; return val; } Object.Destroy((Object)(object)val); } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("加载贴图失败 " + pngPath + ": " + ex.Message)); } return null; } public static bool SaveToPng(Texture? tex, string path) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tex == (Object)null) { return false; } try { Texture2D val = (Texture2D)(object)((tex is Texture2D) ? tex : null); Texture2D val2; if ((Object)(object)val != (Object)null && ((Texture)val).isReadable) { val2 = val; } else { RenderTexture temporary = RenderTexture.GetTemporary(tex.width, tex.height, 0, (RenderTextureFormat)0); Graphics.Blit(tex, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; val2 = new Texture2D(tex.width, tex.height, (TextureFormat)4, false); val2.ReadPixels(new Rect(0f, 0f, (float)tex.width, (float)tex.height), 0, 0); val2.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } byte[] array = ImageConversion.EncodeToPNG(val2); if (array == null || array.Length == 0) { return false; } string directoryName = Path.GetDirectoryName(path); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } File.WriteAllBytes(path, array); CustomItemsPlugin.Log.LogInfo((object)$"已导出贴图: {path} ({tex.width}x{tex.height})"); return true; } catch (Exception ex) { CustomItemsPlugin.Log.LogWarning((object)("导出贴图失败 " + path + ": " + ex.Message)); return false; } } public static Texture2D? GetModelMainTex(Item item) { Renderer val = item.mainRenderer; if ((Object)(object)val == (Object)null && item.addtlRenderers != null && item.addtlRenderers.Length != 0) { val = item.addtlRenderers[0]; } if ((Object)(object)val == (Object)null) { return null; } Material sharedMaterial = val.sharedMaterial; if ((Object)(object)sharedMaterial == (Object)null || !sharedMaterial.HasProperty("_MainTex")) { return null; } Texture mainTexture = sharedMaterial.mainTexture; return (Texture2D?)(object)((mainTexture is Texture2D) ? mainTexture : null); } } }