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<Character>();
if ((Object)(object)component == (Object)null || !IsLox(component) || !IsTamed(component))
{
return;
}
ZNetView component2 = ((Component)component).GetComponent<ZNetView>();
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<MonsterAI>();
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<Tameable>();
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<ZNetView>();
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<Character, bool> _peacefulCache = new Dictionary<Character, bool>();
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<Tameable>();
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<Tameable>();
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<Character, bool> _loxCache = new Dictionary<Character, bool>();
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<Tameable>();
if ((Object)(object)component != (Object)null && component.IsTamed())
{
__result += (BullJackControl.IsPeaceful(__instance) ? " (Спокоен)" : " (Агрессивен)");
}
}
}
}