Decompiled source of BullJackControl v1.2.1

plugins/BullJackControl.dll

Decompiled a month ago
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) ? " (Спокоен)" : " (Агрессивен)");
			}
		}
	}
}