Decompiled source of AnimalGuardian v1.0.0

plugins/AnimalGuardian.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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 AnimalGuardian
{
	[BepInPlugin("hansenbansen.animalguardian", "Animal Guardian", "1.0.0")]
	public class AnimalGuardianPlugin : BaseUnityPlugin
	{
		public const string Guid = "hansenbansen.animalguardian";

		public const string Version = "1.0.0";

		public static ManualLogSource Log;

		private static Harmony s_harmony;

		private void Awake()
		{
			Install(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger, Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
		}

		public static void Install(ConfigFile config, ManualLogSource logger, string pluginDirectory)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			Log = logger;
			Settings.Bind(config);
			s_harmony = new Harmony("hansenbansen.animalguardian");
			s_harmony.PatchAll(typeof(AnimalGuardianPlugin).Assembly);
			Log.LogInfo((object)"Animal Guardian 1.0.0 loaded");
		}

		public static void Uninstall()
		{
			Harmony obj = s_harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			s_harmony = null;
			Truce.Forget();
		}
	}
	internal enum Protection
	{
		Ward,
		Everywhere
	}
	internal static class Settings
	{
		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<Protection> Where;

		public static ConfigEntry<bool> FightBack;

		public static void Bind(ConfigFile config)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			Enabled = config.Bind<bool>("General", "Enabled", true, new ConfigDescription("Creatures that come with a raid leave tamed animals alone: they do not go for them and their attacks do not hurt them.", (AcceptableValueBase)null, Array.Empty<object>()));
			ConfigDefinition val = new ConfigDefinition("General", "Protection");
			string text = null;
			if (config.ContainsKey(val) && config[val].SettingType != typeof(Protection))
			{
				text = config[val].GetSerializedValue();
				config.Remove(val);
			}
			Where = config.Bind<Protection>(val, Protection.Ward, new ConfigDescription("Ward: only tamed animals standing inside an active ward's area are spared (a ward that is switched on). Everywhere: tamed animals are spared anywhere.", (AcceptableValueBase)null, Array.Empty<object>()));
			if (text != null)
			{
				((ConfigEntryBase)Where).SetSerializedValue(text);
			}
			FightBack = config.Bind<bool>("General", "FightBack", false, new ConfigDescription("A raider that a tamed animal attacks may fight back against that animal (only that one). Off: raiders never fight tamed animals, even ones that attack them.", (AcceptableValueBase)null, Array.Empty<object>()));
		}
	}
	internal static class Truce
	{
		private static ConditionalWeakTable<Character, HashSet<Character>> s_provoked = new ConditionalWeakTable<Character, HashSet<Character>>();

		public static bool IsRaider(Character character)
		{
			if (character.IsPlayer() || character.IsTamed())
			{
				return false;
			}
			BaseAI baseAI = character.GetBaseAI();
			MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
			if (val != null && (Object)(object)((BaseAI)val).m_nview != (Object)null && ((BaseAI)val).m_nview.IsValid())
			{
				return val.IsEventCreature();
			}
			return false;
		}

		public static bool IsTame(Character character)
		{
			if (!character.IsPlayer())
			{
				return character.IsTamed();
			}
			return false;
		}

		public static bool Spares(Character raider, Character other)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!Settings.Enabled.Value || !Object.op_Implicit((Object)(object)raider) || !Object.op_Implicit((Object)(object)other))
			{
				return false;
			}
			if (!IsTame(other) || !IsRaider(raider))
			{
				return false;
			}
			if (Settings.Where.Value == Protection.Ward && !Wards.Cover(((Component)other).transform.position))
			{
				return false;
			}
			if (Settings.FightBack.Value)
			{
				return !WasProvokedBy(raider, other);
			}
			return true;
		}

		public static bool WasProvokedBy(Character raider, Character tame)
		{
			if (s_provoked.TryGetValue(raider, out var value))
			{
				return value.Contains(tame);
			}
			return false;
		}

		public static void Provoke(Character raider, Character tame)
		{
			s_provoked.GetOrCreateValue(raider).Add(tame);
		}

		public static void Forget()
		{
			s_provoked = new ConditionalWeakTable<Character, HashSet<Character>>();
		}
	}
	[HarmonyPatch(typeof(BaseAI), "IsEnemy", new Type[]
	{
		typeof(Character),
		typeof(Character)
	})]
	internal static class IsEnemyPatch
	{
		private static void Postfix(Character a, Character b, ref bool __result)
		{
			if (__result && Truce.Spares(a, b))
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "OnDamaged")]
	internal static class OnDamagedPatch
	{
		private static void Prefix(MonsterAI __instance, Character attacker)
		{
			if (Settings.Enabled.Value && Settings.FightBack.Value && !((Object)(object)attacker == (Object)null))
			{
				Character character = ((BaseAI)__instance).m_character;
				if ((Object)(object)character != (Object)null && Truce.IsTame(attacker) && Truce.IsRaider(character))
				{
					Truce.Provoke(character, attacker);
				}
			}
		}
	}
	internal static class Wards
	{
		private static readonly FieldRef<List<PrivateArea>, int> s_version = FindVersion();

		private static List<PrivateArea> s_copiedList;

		private static int s_copiedVersion;

		private static PrivateArea[] s_areas = (PrivateArea[])(object)new PrivateArea[0];

		private static float[] s_x = new float[0];

		private static float[] s_z = new float[0];

		private static float[] s_radius2 = new float[0];

		private static bool[] s_enabled = new bool[0];

		private static float[] s_enabledRead = new float[0];

		internal static bool Cached => s_version != null;

		public static bool Cover(Vector3 point)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			List<PrivateArea> allAreas = PrivateArea.m_allAreas;
			if (s_version == null)
			{
				return CoverUncached(allAreas, point);
			}
			if (allAreas != s_copiedList || s_version.Invoke(allAreas) != s_copiedVersion)
			{
				Copy(allAreas);
			}
			for (int i = 0; i < s_areas.Length; i++)
			{
				float num = point.x - s_x[i];
				float num2 = point.z - s_z[i];
				if (num * num + num2 * num2 < s_radius2[i] && IsEnabled(i))
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsEnabled(int i)
		{
			float time = Time.time;
			if (time - s_enabledRead[i] > 1f || time < s_enabledRead[i])
			{
				s_enabledRead[i] = time;
				s_enabled[i] = (Object)(object)s_areas[i] != (Object)null && s_areas[i].IsEnabled();
			}
			return s_enabled[i];
		}

		private static void Copy(List<PrivateArea> areas)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			List<PrivateArea> list = new List<PrivateArea>(areas.Count);
			foreach (PrivateArea area in areas)
			{
				if ((Object)(object)area != (Object)null && (int)area.m_ownerFaction == 0)
				{
					list.Add(area);
				}
			}
			s_areas = list.ToArray();
			s_x = new float[s_areas.Length];
			s_z = new float[s_areas.Length];
			s_radius2 = new float[s_areas.Length];
			s_enabled = new bool[s_areas.Length];
			s_enabledRead = new float[s_areas.Length];
			for (int i = 0; i < s_areas.Length; i++)
			{
				Vector3 position = ((Component)s_areas[i]).transform.position;
				s_x[i] = position.x;
				s_z[i] = position.z;
				s_radius2[i] = s_areas[i].m_radius * s_areas[i].m_radius;
				s_enabledRead[i] = float.NegativeInfinity;
			}
			s_copiedList = areas;
			s_copiedVersion = s_version.Invoke(areas);
		}

		private static bool CoverUncached(List<PrivateArea> areas, Vector3 point)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < areas.Count; i++)
			{
				PrivateArea val = areas[i];
				if (!((Object)(object)val == (Object)null) && (int)val.m_ownerFaction == 0)
				{
					Vector3 position = ((Component)val).transform.position;
					float num = point.x - position.x;
					float num2 = point.z - position.z;
					if (num * num + num2 * num2 < val.m_radius * val.m_radius && val.IsEnabled())
					{
						return true;
					}
				}
			}
			return false;
		}

		private static FieldRef<List<PrivateArea>, int> FindVersion()
		{
			if (AccessTools.Field(typeof(List<PrivateArea>), "_version") == null)
			{
				ManualLogSource log = AnimalGuardianPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"List has no _version here: wards are read straight off the game's list each time");
				}
				return null;
			}
			return AccessTools.FieldRefAccess<List<PrivateArea>, int>("_version");
		}

		internal static bool CoverDirect(Vector3 point)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CoverUncached(PrivateArea.m_allAreas, point);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}