Decompiled source of TruckSafeZone v1.0.0

TruckSafeZone.dll

Decompiled 15 hours ago
using System;
using System.Diagnostics;
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 TruckSafeZone.Patches;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[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 TruckSafeZone
{
	[BepInPlugin("benjamin.trucksafezone", "TruckSafeZone", "1.0.0")]
	[BepInProcess("REPO.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "benjamin.trucksafezone";

		public const string Name = "TruckSafeZone";

		public const string Version = "1.0.0";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> BlindEnemies;

		internal static ConfigEntry<bool> BlockEnemyDamage;

		internal static ConfigEntry<bool> BlockAllDamage;

		internal static ConfigEntry<bool> PreventDeath;

		internal static ConfigEntry<bool> RepelEnemies;

		internal static ConfigEntry<float> RepelRadius;

		internal static ConfigEntry<float> RepelInterval;

		internal static ConfigEntry<bool> Verbose;

		private void Awake()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. Turn off to disable the safe zone entirely without uninstalling.");
			BlindEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "BlindEnemies", true, "Enemies cannot see or register players standing inside the truck. HOST ONLY - enemy AI runs on the host.");
			BlockEnemyDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "BlockEnemyDamage", true, "Players inside the truck take no damage from enemies. Each player needs the mod for their own protection.");
			BlockAllDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "BlockAllDamage", false, "Block ALL damage inside the truck, including fall damage and friendly fire. Off by default so you can still hurt yourself being an idiot.");
			PreventDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("Safety", "PreventDeath", true, "Last-resort catch: cancel instant-kill grabs (Robe, Apex Predator, etc.) if the player is inside the truck.");
			RepelEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("Repel", "RepelEnemies", true, "Force enemies that wander within RepelRadius of the truck to leave. HOST ONLY.");
			RepelRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Repel", "RepelRadius", 6f, new ConfigDescription("Radius in metres around the truck safety spawn point that enemies get pushed out of.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
			RepelInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Repel", "RepelInterval", 1f, new ConfigDescription("How often (seconds) to scan for enemies near the truck. Higher = cheaper.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
			Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Verbose", false, "Log every time the safe zone blocks something. Noisy.");
			_harmony = new Harmony("benjamin.trucksafezone");
			_harmony.PatchAll(typeof(VisionPatch));
			_harmony.PatchAll(typeof(DamagePatch));
			_harmony.PatchAll(typeof(DeathPatch));
			((Component)this).gameObject.AddComponent<TruckZoneWatcher>();
			Log.LogInfo((object)"TruckSafeZone v1.0.0 loaded. Truck is now a safe zone.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		internal static void Trace(string msg)
		{
			if (Verbose != null && Verbose.Value)
			{
				Log.LogInfo((object)msg);
			}
		}
	}
	internal static class SafeZone
	{
		internal static bool IsPlayerSafe(PlayerAvatar player)
		{
			if (!Plugin.Enabled.Value)
			{
				return false;
			}
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (!SemiFunc.RunIsLevel())
			{
				return false;
			}
			RoomVolumeCheck roomVolumeCheck = player.RoomVolumeCheck;
			if ((Object)(object)roomVolumeCheck == (Object)null)
			{
				return false;
			}
			return roomVolumeCheck.inTruck;
		}

		internal static bool IsLocalPlayerSafe()
		{
			return IsPlayerSafe(PlayerAvatar.instance);
		}

		internal static bool TryGetTruckPosition(out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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)
			position = Vector3.zero;
			TruckSafetySpawnPoint instance = TruckSafetySpawnPoint.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			position = ((Component)instance).transform.position;
			return true;
		}
	}
	internal class TruckZoneWatcher : MonoBehaviour
	{
		private float _timer;

		private void Update()
		{
			if (Plugin.Enabled.Value && Plugin.RepelEnemies.Value && SemiFunc.IsMasterClientOrSingleplayer() && SemiFunc.RunIsLevel())
			{
				_timer -= Time.deltaTime;
				if (!(_timer > 0f))
				{
					_timer = Plugin.RepelInterval.Value;
					Sweep();
				}
			}
		}

		private void Sweep()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (!SafeZone.TryGetTruckPosition(out var position))
			{
				return;
			}
			float value = Plugin.RepelRadius.Value;
			if (value <= 0f)
			{
				return;
			}
			float num = value * value;
			Enemy[] array = Object.FindObjectsOfType<Enemy>();
			foreach (Enemy val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				EnemyParent enemyParent = val.EnemyParent;
				if ((Object)(object)enemyParent == (Object)null || !enemyParent.Spawned || enemyParent.forceLeave)
				{
					continue;
				}
				Vector3 val2 = (((Object)(object)val.CenterTransform != (Object)null) ? val.CenterTransform.position : ((Component)val).transform.position) - position;
				if (!(((Vector3)(ref val2)).sqrMagnitude > num))
				{
					if (val.HasVision && (Object)(object)val.Vision != (Object)null)
					{
						val.Vision.DisableVision(3f);
					}
					enemyParent.forceLeave = true;
					Plugin.Trace("[TruckSafeZone] Repelled '" + enemyParent.enemyName + "' from the truck.");
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TruckSafeZone";

		public const string PLUGIN_NAME = "TruckSafeZone";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace TruckSafeZone.Patches
{
	[HarmonyPatch(typeof(EnemyVision))]
	internal static class VisionPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("VisionTrigger")]
		private static bool BeforeVisionTrigger(int playerID, PlayerAvatar player, bool culled, bool playerNear)
		{
			if (!Plugin.Enabled.Value || !Plugin.BlindEnemies.Value)
			{
				return true;
			}
			if (!SafeZone.IsPlayerSafe(player))
			{
				return true;
			}
			Plugin.Trace("[TruckSafeZone] Suppressed vision trigger for " + player.playerName + " (in truck).");
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerHealth))]
	internal static class DamagePatch
	{
		private static bool ShouldBlock(PlayerHealth health, int enemyIndex)
		{
			if (!Plugin.Enabled.Value)
			{
				return false;
			}
			if ((Object)(object)health == (Object)null)
			{
				return false;
			}
			if (!SafeZone.IsPlayerSafe(health.playerAvatar))
			{
				return false;
			}
			bool flag = enemyIndex >= 0;
			if (Plugin.BlockAllDamage.Value)
			{
				return true;
			}
			if (flag)
			{
				return Plugin.BlockEnemyDamage.Value;
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Hurt")]
		private static bool BeforeHurt(PlayerHealth __instance, int damage, bool savingGrace, int enemyIndex, bool hurtByHeal)
		{
			if (!ShouldBlock(__instance, enemyIndex))
			{
				return true;
			}
			Plugin.Trace($"[TruckSafeZone] Blocked {damage} damage (enemyIndex {enemyIndex}) - player in truck.");
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("HurtOther")]
		private static bool BeforeHurtOther(PlayerHealth __instance, int damage, Vector3 hurtPosition, bool savingGrace, int enemyIndex, bool hurtByHeal)
		{
			if (!ShouldBlock(__instance, enemyIndex))
			{
				return true;
			}
			Plugin.Trace($"[TruckSafeZone] Blocked {damage} remote damage (enemyIndex {enemyIndex}) - player in truck.");
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar))]
	internal static class DeathPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("PlayerDeath")]
		private static bool BeforePlayerDeath(PlayerAvatar __instance, int enemyIndex)
		{
			if (!Plugin.Enabled.Value || !Plugin.PreventDeath.Value)
			{
				return true;
			}
			if (enemyIndex < 0)
			{
				return true;
			}
			if (!SafeZone.IsPlayerSafe(__instance))
			{
				return true;
			}
			Plugin.Trace("[TruckSafeZone] Cancelled enemy kill on " + __instance.playerName + " - player in truck.");
			return false;
		}
	}
}