using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("BullJackControl")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BullJackControl")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ec2134fa-0a78-405a-9a17-246ef3e9241b")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace BullJackControl; [BepInPlugin("bulljack.control.mod", "BullJack Control", "1.2.1")] public class BullJackControl : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("bulljack.control.mod"); private const string PEACEFUL_KEY = "BullJack_Peaceful"; internal static FieldInfo _hoverField; internal static FieldInfo _alertField; internal static FieldInfo _targetField; internal static FieldInfo _lookField; internal static FieldInfo _aiTargetField; internal static FieldInfo _aiAlertedField; internal static FieldInfo _aiAttackTargetField; internal static FieldInfo _characterField; private void Awake() { InitializeReflectionCache(); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BullJack Control мод загружен!"); } private void InitializeReflectionCache() { _hoverField = typeof(Player).GetField("m_hovering", BindingFlags.Instance | BindingFlags.NonPublic); _alertField = typeof(Character).GetField("m_alerted", BindingFlags.Instance | BindingFlags.NonPublic); _targetField = typeof(Character).GetField("m_target", BindingFlags.Instance | BindingFlags.NonPublic); _lookField = typeof(Character).GetField("m_lookTarget", BindingFlags.Instance | BindingFlags.NonPublic); _characterField = typeof(MonsterAI).GetField("m_character", BindingFlags.Instance | BindingFlags.NonPublic); _aiTargetField = typeof(MonsterAI).GetField("m_target", BindingFlags.Instance | BindingFlags.NonPublic); _aiAlertedField = typeof(MonsterAI).GetField("m_alerted", BindingFlags.Instance | BindingFlags.NonPublic); _aiAttackTargetField = typeof(MonsterAI).GetField("m_attackTarget", BindingFlags.Instance | BindingFlags.NonPublic); } private void Update() { if (!((Object)(object)Player.m_localPlayer == (Object)null) && Input.GetKey((KeyCode)306) && Input.GetKeyDown((KeyCode)98)) { ToggleLoxState(); } } private void ToggleLoxState() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } object? obj = _hoverField?.GetValue(localPlayer); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (!((Object)(object)val != (Object)null)) { return; } Character component = val.GetComponent(); if ((Object)(object)component == (Object)null || !IsLox(component) || !IsTamed(component)) { return; } ZNetView component2 = ((Component)component).GetComponent(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { bool @bool = component2.GetZDO().GetBool("BullJack_Peaceful", false); bool flag = !@bool; component2.GetZDO().Set("BullJack_Peaceful", flag); if (flag) { ResetCombatState(component); } string text = (flag ? "спокоен" : "агрессивен"); ShowMessage("Прирученный быкоящер теперь " + text); } } private void ResetCombatState(Character character) { if (!((Object)(object)character == (Object)null)) { _alertField?.SetValue(character, false); _targetField?.SetValue(character, null); _lookField?.SetValue(character, null); MonsterAI component = ((Component)character).GetComponent(); if ((Object)(object)component != (Object)null) { _aiTargetField?.SetValue(component, null); _aiAlertedField?.SetValue(component, false); _aiAttackTargetField?.SetValue(component, null); } } } private bool IsLox(Character character) { if ((Object)(object)character == (Object)null) { return false; } string text = ((Object)character).name.ToLower(); return text.Contains("lox") || text.Contains("bull"); } private bool IsTamed(Character character) { if ((Object)(object)character == (Object)null) { return false; } Tameable component = ((Component)character).GetComponent(); return (Object)(object)component != (Object)null && component.IsTamed(); } private void ShowMessage(string message) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, message, 0, (Sprite)null, false); } } public static bool IsPeaceful(Character character) { if ((Object)(object)character == (Object)null) { return false; } ZNetView component = ((Component)character).GetComponent(); return (Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("BullJack_Peaceful", false); } } [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] public static class MonsterAI_UpdateAI_Patch { [HarmonyPatch(typeof(Character), "OnDestroy")] private static class Character_OnDestroy_Patch { private static void Postfix(Character __instance) { _peacefulCache.Remove(__instance); } } private static readonly Dictionary _peacefulCache = new Dictionary(); private static void Postfix(MonsterAI __instance, float dt) { object? obj = BullJackControl._characterField?.GetValue(__instance); Character val = (Character)((obj is Character) ? obj : null); if (!((Object)(object)val != (Object)null)) { return; } if (!_peacefulCache.TryGetValue(val, out var value)) { value = BullJackControl.IsPeaceful(val); _peacefulCache[val] = value; } if (value) { Tameable component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null && component.IsTamed()) { BullJackControl._aiTargetField?.SetValue(__instance, null); BullJackControl._aiAttackTargetField?.SetValue(__instance, null); BullJackControl._aiAlertedField?.SetValue(__instance, false); } } } } [HarmonyPatch(typeof(Character), "OnDamaged")] public static class Character_OnDamaged_Patch { private static bool Prefix(Character __instance, HitData hit) { if ((Object)(object)__instance == (Object)null) { return true; } return !BullJackControl.IsPeaceful(__instance); } } [HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[] { typeof(Character), typeof(Character) })] public static class BaseAI_IsEnemy_Patch { private static void Postfix(Character a, Character b, ref bool __result) { if ((Object)(object)a != (Object)null && (Object)(object)b != (Object)null && BullJackControl.IsPeaceful(a)) { Tameable component = ((Component)a).GetComponent(); if ((Object)(object)component != (Object)null && component.IsTamed()) { __result = false; } } } } [HarmonyPatch(typeof(Character), "GetHoverName")] public static class Character_GetHoverName_Patch { [HarmonyPatch(typeof(Character), "OnDestroy")] private static class Character_OnDestroy_Cache_Patch { private static void Postfix(Character __instance) { _loxCache.Remove(__instance); } } private static readonly Dictionary _loxCache = new Dictionary(); private static void Postfix(Character __instance, ref string __result) { if ((Object)(object)__instance == (Object)null) { return; } if (!_loxCache.TryGetValue(__instance, out var value)) { string text = ((Object)__instance).name.ToLower(); value = text.Contains("lox") || text.Contains("bull"); _loxCache[__instance] = value; } if (value) { Tameable component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.IsTamed()) { __result += (BullJackControl.IsPeaceful(__instance) ? " (Спокоен)" : " (Агрессивен)"); } } } }