Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AiFree v1.1.1
BepInEx/plugins/AiFree/AiFree.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 AiFree { [BepInPlugin("captain.aifree", "AiFree", "1.1.1")] public class Plugin : BaseUnityPlugin { public const string GUID = "captain.aifree"; public const string NAME = "AiFree"; public const string VERSION = "1.1.1"; internal static Plugin Instance; public static ManualLogSource Log; internal static ConfigEntry<float> SenseTimeout; internal static ConfigEntry<bool> KeepZonesLoaded; private Harmony _harmony; private void Awake() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; SenseTimeout = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SenseTimeout", 0f, "몬스터가 타겟을 잃은 후 포기까지의 대기 시간(초).\n0 = 절대 포기하지 않음 (타겟이 죽을 때까지 유지).\n원래 게임 기본값은 30f 입니다."); KeepZonesLoaded = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "KeepZonesLoaded", true, "true = 전투 중인 몬스터(공격자·피격자 모두)의 구역을 플레이어가 멀리 떠나도 언로드하지 않음.\n싱글플레이어 포탈 이탈 시에도 전투가 계속 진행됩니다.\nfalse = 원래 게임 동작 (구역 언로드 시 AI 정지)."); _harmony = new Harmony("captain.aifree"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Troll:벽관통보정] 패치 로드됨 (고정 동작, 토글 없음)."); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[{0}] {1} 로드 완료 — SenseTimeout: {2}, KeepZonesLoaded: {3}", "AiFree", "1.1.1", SenseTimeout.Value, KeepZonesLoaded.Value)); } } } namespace AiFree.Patches { [HarmonyPatch(typeof(MonsterAI), "UpdateTarget")] internal static class MonsterAIPatch { private static readonly FieldInfo _targetCreatureField = AccessTools.Field(typeof(MonsterAI), "m_targetCreature"); private static readonly FieldInfo _timeSensedField = AccessTools.Field(typeof(MonsterAI), "m_timeSinceSensedTargetCreature"); [HarmonyPrefix] private static void Prefix(MonsterAI __instance) { object? value = _targetCreatureField.GetValue(__instance); Character val = (Character)((value is Character) ? value : null); if ((Object)(object)val == (Object)null || val.IsDead()) { return; } float value2 = Plugin.SenseTimeout.Value; if (value2 <= 0f) { _timeSensedField.SetValue(__instance, 0f); return; } float num = (float)_timeSensedField.GetValue(__instance); if (num >= value2) { _timeSensedField.SetValue(__instance, 0f); } } } internal static class WallPenetrateTargets { public static readonly string[] Names = new string[1] { "Troll" }; public static bool Contains(string prefabName) { string[] names = Names; foreach (string text in names) { if (text == prefabName) { return true; } } return false; } } [HarmonyPatch(typeof(Attack), "OnAttackTrigger")] public static class TrollWallPenetratePatch { private static readonly FieldInfo s_charField = AccessTools.Field(typeof(Attack), "m_character"); private static readonly FieldInfo s_weaponField = AccessTools.Field(typeof(Attack), "m_weapon"); private static readonly FieldInfo s_rangeField = AccessTools.Field(typeof(Attack), "m_attackRange"); private static readonly MethodInfo s_getOriginMethod = AccessTools.Method(typeof(Attack), "GetAttackOrigin", (Type[])null, (Type[])null); private static int s_wallMask = 0; [HarmonyPostfix] private static void Postfix(Attack __instance) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014b: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0180: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) if (s_charField == null || s_weaponField == null || s_rangeField == null || s_getOriginMethod == null) { return; } object? value = s_charField.GetValue(__instance); Character val = (Character)((value is Character) ? value : null); if ((Object)(object)val == (Object)null) { return; } string prefabName = Utils.GetPrefabName(((Component)val).gameObject); if (!WallPenetrateTargets.Contains(prefabName)) { return; } object? value2 = s_weaponField.GetValue(__instance); ItemData val2 = (ItemData)((value2 is ItemData) ? value2 : null); if (val2 == null) { return; } if (s_wallMask == 0) { s_wallMask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" }); } object? obj = s_getOriginMethod.Invoke(__instance, null); Transform val3 = (Transform)((obj is Transform) ? obj : null); if ((Object)(object)val3 == (Object)null) { return; } float num = (float)s_rangeField.GetValue(__instance); foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer == (Object)null || ((Character)allPlayer).IsDead()) { continue; } Vector3 val4 = ((Character)allPlayer).GetCenterPoint() - val3.position; float magnitude = ((Vector3)(ref val4)).magnitude; if (!(magnitude > num)) { Vector3 normalized = ((Vector3)(ref val4)).normalized; if (!(Vector3.Dot(((Component)val).transform.forward, normalized) < 0f) && Physics.Raycast(val3.position, normalized, magnitude, s_wallMask, (QueryTriggerInteraction)1)) { HitData val5 = new HitData(); val5.m_damage = val2.GetDamage(); val5.m_point = ((Character)allPlayer).GetCenterPoint(); val5.m_dir = normalized; val5.m_pushForce = val2.m_shared.m_attackForce; val5.m_blockable = val2.m_shared.m_blockable; val5.m_dodgeable = val2.m_shared.m_dodgeable; val5.SetAttacker(val); val5.m_hitType = (HitType)1; ((Character)allPlayer).Damage(val5); Plugin.Log.LogInfo((object)$"[{prefabName}:벽관통보정] 벽에 막힌 플레이어({allPlayer.GetPlayerName()})에게 추가 데미지 적용 (dist={magnitude:F1}m)"); } } } } } [HarmonyPatch(typeof(ZNetScene), "RemoveObjects")] internal static class ZNetScenePatch { private static readonly FieldInfo _instancesField = AccessTools.Field(typeof(ZNetScene), "m_instances"); private static readonly FieldInfo _targetCreatureField = AccessTools.Field(typeof(MonsterAI), "m_targetCreature"); [HarmonyPrefix] private static void Prefix(List<ZDO> currentNearObjects) { if (!Plugin.KeepZonesLoaded.Value) { return; } ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || !(_instancesField.GetValue(instance) is Dictionary<ZDO, ZNetView> collection)) { return; } List<KeyValuePair<ZDO, ZNetView>> list = new List<KeyValuePair<ZDO, ZNetView>>(collection); foreach (KeyValuePair<ZDO, ZNetView> item in list) { ZNetView value = item.Value; if ((Object)(object)value == (Object)null || !Object.op_Implicit((Object)(object)value)) { continue; } MonsterAI component = ((Component)value).GetComponent<MonsterAI>(); if ((Object)(object)component == (Object)null) { continue; } object? value2 = _targetCreatureField.GetValue(component); Character val = (Character)((value2 is Character) ? value2 : null); if ((Object)(object)val == (Object)null || val.IsDead()) { continue; } ZDO key = item.Key; if (!currentNearObjects.Contains(key)) { currentNearObjects.Add(key); } ZNetView component2 = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && Object.op_Implicit((Object)(object)component2)) { ZDO zDO = component2.GetZDO(); if (zDO != null && !currentNearObjects.Contains(zDO)) { currentNearObjects.Add(zDO); } } } } } }