114 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			114 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						||
using HarmonyLib;
 | 
						||
using ItemStatsSystem;
 | 
						||
using ItemStatsSystem.Items;
 | 
						||
using System.Reflection;
 | 
						||
using System.Collections.Generic;
 | 
						||
using Duckov.Utilities;
 | 
						||
 | 
						||
namespace test
 | 
						||
{
 | 
						||
    /// <summary>
 | 
						||
    /// 注射器收纳包槽位修改补丁
 | 
						||
    /// 将注射器收纳包(ID 882)的槽位数量从6个修改为12个
 | 
						||
    /// </summary>
 | 
						||
    [HarmonyPatch(typeof(Item))]
 | 
						||
    [HarmonyPatch("Initialize")]
 | 
						||
    public class InjectionBagSlotPatch
 | 
						||
    {
 | 
						||
        private const int InjectionBagTypeID = 882;
 | 
						||
        private const int TargetSlotCount = 12;
 | 
						||
        private const int AdditionalSlots = 6;
 | 
						||
        
 | 
						||
        // 记录已经修改过的物品,避免重复修改
 | 
						||
        private static readonly HashSet<int> modifiedItems = new HashSet<int>();
 | 
						||
        
 | 
						||
        // 缓存反射方法,避免重复获取
 | 
						||
        private static readonly ConstructorInfo SlotConstructor = typeof(Slot).GetConstructor(new Type[] { typeof(string) });
 | 
						||
        private static readonly FieldInfo RequireTagsField = typeof(Slot).GetField("requireTags", BindingFlags.Public | BindingFlags.Instance);
 | 
						||
        private static readonly MethodInfo SlotInitializeMethod = typeof(Slot).GetMethod("Initialize", BindingFlags.Public | BindingFlags.Instance);
 | 
						||
        private static readonly MethodInfo BuildDictionaryMethod = typeof(SlotCollection).GetMethod("BuildDictionary", BindingFlags.NonPublic | BindingFlags.Instance);
 | 
						||
 | 
						||
        /// <summary>
 | 
						||
        /// Initialize方法的后缀补丁
 | 
						||
        /// 在物品初始化后检查是否是注射器收纳包
 | 
						||
        /// 槽位默认6个,变为12个
 | 
						||
        /// </summary>
 | 
						||
        /// <param name="__instance">Item实例</param>
 | 
						||
        [HarmonyPostfix]
 | 
						||
        static void Postfix(Item __instance)
 | 
						||
        {
 | 
						||
            // 快速检查:是否是注射器收纳包
 | 
						||
            if (__instance?.TypeID != InjectionBagTypeID || __instance.Slots == null)
 | 
						||
                return;
 | 
						||
                
 | 
						||
            // 检查是否已经修改过这个物品实例
 | 
						||
            int instanceId = __instance.GetInstanceID();
 | 
						||
            if (!modifiedItems.Add(instanceId)) // 使用Add的返回值检查是否已存在
 | 
						||
                return;
 | 
						||
 | 
						||
            // 获取槽位集合
 | 
						||
            SlotCollection slots = __instance.Slots;
 | 
						||
            
 | 
						||
            // 获取原始槽位数量
 | 
						||
            int originalSlotCount = slots.Count;
 | 
						||
            
 | 
						||
            // 如果已经是目标槽位数量,则不需要修改
 | 
						||
            if (originalSlotCount == TargetSlotCount)
 | 
						||
                return;
 | 
						||
 | 
						||
            // 获取第一个槽位的标签,用于复制
 | 
						||
            List<Tag> firstSlotTags = null;
 | 
						||
            if (originalSlotCount > 0 && slots.list.Count > 0)
 | 
						||
            {
 | 
						||
                var firstSlot = slots.list[0];
 | 
						||
                if (firstSlot != null)
 | 
						||
                {
 | 
						||
                    firstSlotTags = RequireTagsField?.GetValue(firstSlot) as List<Tag>;
 | 
						||
                }
 | 
						||
            }
 | 
						||
 | 
						||
            // 预分配槽位列表容量,减少内存重新分配
 | 
						||
            if (slots.list.Capacity < originalSlotCount + AdditionalSlots)
 | 
						||
            {
 | 
						||
                slots.list.Capacity = originalSlotCount + AdditionalSlots;
 | 
						||
            }
 | 
						||
 | 
						||
            // 添加6个新的槽位
 | 
						||
            for (int i = 0; i < AdditionalSlots; i++)
 | 
						||
            {
 | 
						||
                // 设置Slot的Key属性
 | 
						||
                string slotKey = $"InjectionSlot_{originalSlotCount + i + 1}";
 | 
						||
                
 | 
						||
                // 使用缓存的构造函数创建新的Slot对象
 | 
						||
                Slot newSlot = SlotConstructor?.Invoke(new object[] { slotKey }) as Slot;
 | 
						||
 | 
						||
                // 复制第一个槽位的requireTags
 | 
						||
                if (newSlot != null && firstSlotTags != null && firstSlotTags.Count > 0)
 | 
						||
                {
 | 
						||
                    // 创建新的Tag列表并复制第一个槽位的Tag
 | 
						||
                    var newTags = new List<Tag>(firstSlotTags.Count);
 | 
						||
                    for (int j = 0; j < firstSlotTags.Count; j++)
 | 
						||
                    {
 | 
						||
                        var tag = firstSlotTags[j];
 | 
						||
                        if (tag != null)
 | 
						||
                        {
 | 
						||
                            newTags.Add(tag);
 | 
						||
                        }
 | 
						||
                    }
 | 
						||
                    RequireTagsField?.SetValue(newSlot, newTags);
 | 
						||
                }
 | 
						||
 | 
						||
                // 初始化Slot
 | 
						||
                SlotInitializeMethod?.Invoke(newSlot, new object[] { slots });
 | 
						||
 | 
						||
                // 添加到槽位列表
 | 
						||
                slots.list.Add(newSlot);
 | 
						||
            }
 | 
						||
 | 
						||
            // 重建字典缓存
 | 
						||
            BuildDictionaryMethod?.Invoke(slots, null);
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |