using System; using HarmonyLib; using UnityEngine; namespace NecromancerTome { /// /// Стрела: NullReferenceException в ItemAction.GetDismemberChance (23.10.2026). Вызывается из ProjectileMoveScript.checkCollision /// аргументом к ItemActionAttack.Hit - поэтому в первых логах исключение выглядело как ошибка «внутри Hit» (метод был встроен). /// Пустое звено цепочки actionData.invData.holdingEntity.inventory / invData.item у стрелы, запомнившей данные лука при выстреле. /// Исключение вылетало раньше, чем стрела сменит состояние, и она «попадала» снова каждый шаг физики - пачки по 6-19 ошибок. /// Здесь: при исключении шанс отстрела конечности 0 (стрела долетает как обычно), в лог - какое звено пустое (не больше /// MaxLogs раз за запуск). Причина звена - выяснить по этим строкам. /// [HarmonyPatch(typeof(ItemAction), nameof(ItemAction.GetDismemberChance))] public static class Patch_ItemAction_GetDismemberChance_Guard { const int MaxLogs = 5; static int _logged; public static Exception Finalizer(Exception __exception, ItemActionData _actionData, WorldRayHitInfo hitInfo, ref float __result) { if (__exception == null) { return null; } __result = 0f; if (_logged < MaxLogs) { _logged++; try { ItemInventoryData inv = _actionData?.invData; EntityAlive holder = inv?.holdingEntity; Debug.Log("[NecromancerTome] DismemberGuard: " + __exception.GetType().Name + " в GetDismemberChance - actionData " + (_actionData == null ? "NULL" : _actionData.GetType().Name) + ", invData " + (inv == null ? "NULL" : "slot " + inv.slotIdx) + ", item " + (inv?.item == null ? "NULL" : inv.item.Name) + ", holdingEntity " + (holder == null ? "NULL" : holder.GetType().Name + " " + holder.entityId + (holder.IsDead() ? " dead" : "")) + ", inventory " + (holder == null ? "-" : holder.inventory == null ? "NULL" : "в руке " + holder.inventory.holdingItem?.Name) + ", tag " + (hitInfo?.tag ?? "NULL") + " - шанс отстрела 0"); } catch (Exception e2) { Debug.Log("[NecromancerTome] DismemberGuard: не удалось описать - " + e2.Message); } } return null; // проглотить: стрела долетает и попадает как обычно } } }