12格针包

This commit is contained in:
2025-10-25 01:48:42 +08:00
parent 6915ad54ba
commit 58390d5a32
2 changed files with 1164 additions and 19 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,9 @@ using System;
using HarmonyLib; using HarmonyLib;
using ItemStatsSystem; using ItemStatsSystem;
using ItemStatsSystem.Items; using ItemStatsSystem.Items;
using UnityEngine;
using System.Reflection; using System.Reflection;
using System.Collections.Generic;
using Duckov.Utilities;
namespace test namespace test
{ {
@@ -16,6 +17,18 @@ namespace test
public class InjectionBagSlotPatch public class InjectionBagSlotPatch
{ {
private const int InjectionBagTypeID = 882; 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> /// <summary>
/// Initialize方法的后缀补丁 /// Initialize方法的后缀补丁
/// 在物品初始化后检查是否是注射器收纳包 /// 在物品初始化后检查是否是注射器收纳包
@@ -25,41 +38,76 @@ namespace test
[HarmonyPostfix] [HarmonyPostfix]
static void Postfix(Item __instance) static void Postfix(Item __instance)
{ {
Debug.Log($"[注射器收纳包修改] 被调用"); // 快速检查:是否是注射器收纳包
if (__instance?.TypeID != InjectionBagTypeID || __instance.Slots == null)
// 检查是否是注射器收纳包 return;
if (__instance == null || __instance.TypeID != InjectionBagTypeID || __instance.Slots == null)
// 检查是否已经修改过这个物品实例
int instanceId = __instance.GetInstanceID();
if (!modifiedItems.Add(instanceId)) // 使用Add的返回值检查是否已存在
return; return;
// 获取槽位集合 // 获取槽位集合
SlotCollection slots = __instance.Slots; SlotCollection slots = __instance.Slots;
if (slots.Count == 12)
return;
// 获取原始槽位数量 // 获取原始槽位数量
int originalSlotCount = slots.Count; 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个新的槽位 // 添加6个新的槽位
for (int i = 0; i < 6; i++) for (int i = 0; i < AdditionalSlots; i++)
{ {
// 创建新的Slot对象
Slot newSlot = (Slot)typeof(Slot).GetConstructor(new Type[0])?.Invoke(null);
// 设置Slot的Key属性 // 设置Slot的Key属性
typeof(Slot).GetField("Key", BindingFlags.Public | BindingFlags.Instance)?.SetValue(newSlot, $"Slot_{originalSlotCount + i}"); 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); slots.list.Add(newSlot);
// 初始化Slot
typeof(Slot).GetMethod("Initialize", BindingFlags.Public | BindingFlags.Instance)?.Invoke(newSlot, new object[] { slots });
} }
// 重建字典缓存 // 重建字典缓存
typeof(SlotCollection).GetMethod("BuildDictionary", BindingFlags.NonPublic | BindingFlags.Instance)?.Invoke(slots, null); BuildDictionaryMethod?.Invoke(slots, null);
Debug.Log($"[注射器收纳包修改] 已将物品ID {__instance.TypeID} 的槽位数量从{originalSlotCount}修改为{slots.Count}");
} }
} }
} }