This commit is contained in:
Tourswen
2025-11-19 00:46:26 +08:00
parent 878657af47
commit 0d6fb3bf19
7 changed files with 473 additions and 245 deletions

View File

@@ -1,7 +1,7 @@
using HarmonyLib;
using RimWorld;
using System.Linq;
using System.Reflection;
using System;
using System.Collections.Generic;
using UnityEngine;
using Verse;
@@ -10,35 +10,71 @@ namespace WulaFallenEmpire.HarmonyPatches
[HarmonyPatch(typeof(Projectile), "CheckForFreeInterceptBetween")]
public static class Projectile_CheckForFreeInterceptBetween_Patch
{
private static readonly MethodInfo ImpactMethod = AccessTools.Method(typeof(Projectile), "Impact");
public static bool Prefix(Projectile __instance, Vector3 lastExactPos, Vector3 newExactPos)
{
if (__instance.Map == null || __instance.Destroyed) return true;
foreach (Pawn pawn in __instance.Map.mapPawns.AllPawnsSpawned)
try
{
if (pawn.apparel != null)
if (__instance == null || __instance.Map == null || __instance.Destroyed || !__instance.Spawned)
return true;
var map = __instance.Map;
var pawns = map.mapPawns?.AllPawnsSpawned;
if (pawns == null) return true;
foreach (Pawn pawn in pawns)
{
if (pawn == null || !pawn.Spawned || pawn.Dead || pawn.Downed || pawn.apparel == null)
continue;
foreach (Apparel apparel in pawn.apparel.WornApparel)
{
if (apparel.TryGetComp<CompApparelInterceptor>(out var interceptor))
if (apparel?.TryGetComp<CompApparelInterceptor>() is CompApparelInterceptor interceptor)
{
if (interceptor.TryIntercept(__instance, lastExactPos, newExactPos))
try
{
// Directly destroy the projectile instead of calling Impact via reflection.
// This is cleaner and avoids the NRE that happens when the game engine
// continues to process a projectile that was destroyed mid-tick.
__instance.Destroy(DestroyMode.Vanish);
return false; // Prevent original method from running.
if (interceptor.TryIntercept(__instance, lastExactPos, newExactPos))
{
// 简单直接:立即销毁子弹
if (!__instance.Destroyed && __instance.Spawned)
{
__instance.Destroy(DestroyMode.Vanish);
}
return false;
}
}
catch (Exception ex)
{
Log.Warning($"[Interceptor] Error: {ex.Message}");
}
}
}
}
}
return true;
return true;
}
catch (Exception ex)
{
Log.Error($"[Interceptor] Critical error: {ex}");
return true;
}
}
}
}
[HarmonyPatch(typeof(Projectile), "Tick")]
public static class Projectile_Tick_Patch
{
public static bool Prefix(Projectile __instance)
{
return __instance != null && !__instance.Destroyed && __instance.Spawned;
}
}
[HarmonyPatch(typeof(Projectile), "TickInterval")]
public static class Projectile_TickInterval_Patch
{
public static bool Prefix(Projectile __instance, int delta)
{
return __instance != null && !__instance.Destroyed && __instance.Spawned;
}
}
}