Decompiled source of DiagnosticoAltar v1.0.0

BepInEx/plugins/DiagnosticoAltar/DiagnosticoAltar.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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: AssemblyCompany("DiagnosticoAltar")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DiagnosticoAltar")]
[assembly: AssemblyTitle("DiagnosticoAltar")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 DiagnosticoAltar
{
	internal static class EstorbosAltar
	{
		private class Aviso
		{
			public HashSet<string> Claves;

			public float Hora;
		}

		private class Estorbo
		{
			public string Clave;

			public string Nombre;

			public GameObject Objeto;

			public Collider SoloColision;

			public int Rayos;

			public IEnumerable<Collider> Colisiones()
			{
				if (!((Object)(object)Objeto != (Object)null))
				{
					return (IEnumerable<Collider>)(object)new Collider[1] { SoloColision };
				}
				return Objeto.GetComponentsInChildren<Collider>();
			}
		}

		private const float SeparacionRayos = 1f;

		private const int MaxEstorbos = 20;

		private const float FraccionValidaSuficiente = 0.2f;

		private const float SegundosParaConfirmar = 300f;

		private const int NombresEnMensaje = 5;

		private static readonly int MascaraSuelo = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });

		private static readonly int MascaraLibre = LayerMask.GetMask(new string[4] { "Default", "static_solid", "Default_small", "piece" });

		private static readonly int CapaTerreno = LayerMask.NameToLayer("terrain");

		private static readonly Dictionary<string, Aviso> Avisos = new Dictionary<string, Aviso>();

		private static readonly (string prefijo, string nombre)[] NombresDeLugares = new(string, string)[5]
		{
			("TrollCave", "Cueva de trol"),
			("SunkenCrypt", "Cripta hundida"),
			("Crypt", "Cripta"),
			("StoneTower", "Torre de piedra"),
			("Ruin", "Ruinas")
		};

		public static bool Resolver(OfferingBowl altar, Vector3 centro, long jugador)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			bool suficiente;
			Dictionary<string, int> intocables;
			List<Estorbo> list = Planear(altar, centro, out suficiente, out intocables);
			foreach (KeyValuePair<string, int> item in intocables)
			{
				DiagnosticoAltarPlugin.Log.LogWarning((object)("[ALTAR]   no se puede quitar: " + item.Key + " en " + item.Value + " rayos"));
			}
			if (list.Count == 0)
			{
				Avisar(jugador, "No se puede invocar al jefe y no hay nada que se pueda quitar.\nMira el registro [ALTAR].");
				return false;
			}
			string key = ClaveDe(altar);
			string text = ListaDeNombres(list);
			if (!Avisos.TryGetValue(key, out var aviso) || !(Time.time - aviso.Hora <= 300f) || !list.All((Estorbo e) => aviso.Claves.Contains(e.Clave)))
			{
				Avisos[key] = new Aviso
				{
					Claves = new HashSet<string>(list.Select((Estorbo e) => e.Clave)),
					Hora = Time.time
				};
				foreach (Estorbo item2 in list)
				{
					DiagnosticoAltarPlugin.Log.LogWarning((object)("[ALTAR]   estorba: " + item2.Nombre + " (" + item2.Rayos + " rayos) en " + ((object)(((Object)(object)item2.Objeto != (Object)null) ? item2.Objeto.transform.position : ((Component)item2.SoloColision).transform.position)/*cast due to .constrained prefix*/).ToString()));
				}
				Avisar(jugador, "No se puede invocar al jefe. Lo impide: " + text + (suficiente ? "" : " (y algo más que no se puede quitar)") + "\nOfrece otra vez para ELIMINARLOS del mundo y poder invocarlo.");
				return false;
			}
			Avisos.Remove(key);
			foreach (Estorbo item3 in list)
			{
				Quitar(item3);
			}
			Avisar(jugador, "Se eliminó del mundo: " + text);
			return true;
		}

		private static List<Estorbo> Planear(OfferingBowl altar, Vector3 centro, out bool suficiente, out Dictionary<string, int> intocables)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			List<Estorbo> list = new List<Estorbo>();
			List<Collider> list2 = new List<Collider>();
			intocables = new Dictionary<string, int>();
			suficiente = false;
			try
			{
				for (int i = 0; i <= 20; i++)
				{
					int validos;
					int total;
					Dictionary<string, Estorbo> dictionary = Muestrear(altar, centro, out validos, out total, intocables);
					suficiente = total > 0 && (float)validos >= (float)total * 0.2f;
					if (suficiente || i == 20 || dictionary.Count == 0)
					{
						break;
					}
					Estorbo estorbo = dictionary.Values.OrderByDescending((Estorbo e) => e.Rayos).First();
					list.Add(estorbo);
					foreach (Collider item in estorbo.Colisiones())
					{
						if (item.enabled)
						{
							item.enabled = false;
							list2.Add(item);
						}
					}
					intocables.Clear();
				}
			}
			finally
			{
				foreach (Collider item2 in list2)
				{
					if ((Object)(object)item2 != (Object)null)
					{
						item2.enabled = true;
					}
				}
			}
			return list;
		}

		private static Dictionary<string, Estorbo> Muestrear(OfferingBowl altar, Vector3 centro, out int validos, out int total, Dictionary<string, int> intocables)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, Estorbo> dictionary = new Dictionary<string, Estorbo>();
			float spawnBossMaxDistance = altar.m_spawnBossMaxDistance;
			float y = ((Component)altar).transform.position.y;
			Transform root = ((Component)altar).transform.root;
			validos = 0;
			total = 0;
			Vector3 val = default(Vector3);
			RaycastHit val2 = default(RaycastHit);
			Vector3 val3 = default(Vector3);
			for (float num = 0f - spawnBossMaxDistance; num <= spawnBossMaxDistance; num += 1f)
			{
				for (float num2 = 0f - spawnBossMaxDistance; num2 <= spawnBossMaxDistance; num2 += 1f)
				{
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					if (num3 > spawnBossMaxDistance || num3 < altar.m_spawnBossMinDistance)
					{
						continue;
					}
					total++;
					((Vector3)(ref val))..ctor(centro.x + num, centro.y + (float)altar.m_getSolidHeightMargin, centro.z + num2);
					if (!Physics.Raycast(val, Vector3.down, ref val2, 2000f, MascaraSuelo))
					{
						continue;
					}
					List<Collider> list = new List<Collider>();
					if (((RaycastHit)(ref val2)).point.y > y + altar.m_spawnBossMaxYDistance)
					{
						list.Add(((RaycastHit)(ref val2)).collider);
					}
					else
					{
						if (((RaycastHit)(ref val2)).point.y < 0f || y - ((RaycastHit)(ref val2)).point.y > altar.m_spawnBossMaxYDistance || (Object)(object)((RaycastHit)(ref val2)).collider.attachedRigidbody != (Object)null)
						{
							continue;
						}
						if (altar.m_spawnPointClearingRadius > 0f)
						{
							((Vector3)(ref val3))..ctor(val.x, ((RaycastHit)(ref val2)).point.y + altar.m_spawnYOffset, val.z);
							list.AddRange(Physics.OverlapSphere(val3, altar.m_spawnPointClearingRadius, MascaraLibre));
						}
					}
					if (list.Count == 0)
					{
						validos++;
						continue;
					}
					foreach (Collider item in list)
					{
						string text = PorQueNoSePuedeQuitar(item, root);
						if (text != null)
						{
							string key = NombreDePrefab(((Component)((Component)item).transform.root).gameObject) + " (" + text + ")";
							intocables[key] = ((!intocables.TryGetValue(key, out var value)) ? 1 : (value + 1));
							continue;
						}
						Estorbo estorbo = Identificar(item);
						if (dictionary.TryGetValue(estorbo.Clave, out var value2))
						{
							value2.Rayos++;
							continue;
						}
						estorbo.Rayos = 1;
						dictionary[estorbo.Clave] = estorbo;
					}
				}
			}
			return dictionary;
		}

		private static string PorQueNoSePuedeQuitar(Collider c, Transform lugarDelAltar)
		{
			if (((Component)c).gameObject.layer == CapaTerreno)
			{
				return "es terreno";
			}
			if ((Object)(object)c.attachedRigidbody != (Object)null)
			{
				return "se mueve: barco, criatura u objeto suelto";
			}
			if (((Component)c).transform.IsChildOf(lugarDelAltar))
			{
				return "es parte del lugar del altar";
			}
			if ((Object)(object)((Component)c).GetComponentInParent<Player>() != (Object)null || (Object)(object)((Component)c).GetComponentInParent<TombStone>() != (Object)null)
			{
				return "es un jugador o una tumba";
			}
			return null;
		}

		private static Estorbo Identificar(Collider c)
		{
			ZNetView componentInParent = ((Component)c).GetComponentInParent<ZNetView>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.IsValid())
			{
				return new Estorbo
				{
					Clave = ((object)Unsafe.As<ZDOID, ZDOID>(ref componentInParent.GetZDO().m_uid)/*cast due to .constrained prefix*/).ToString(),
					Nombre = NombreVisible(((Component)componentInParent).gameObject),
					Objeto = ((Component)componentInParent).gameObject
				};
			}
			return new Estorbo
			{
				Clave = "local:" + ((Object)c).GetInstanceID(),
				Nombre = NombreDePrefab(((Component)((Component)c).transform.root).gameObject) + " (solo esta sesión)",
				SoloColision = c
			};
		}

		private static void Quitar(Estorbo e)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			foreach (Collider item in e.Colisiones())
			{
				if ((Object)(object)item != (Object)null)
				{
					item.enabled = false;
				}
			}
			if ((Object)(object)e.Objeto == (Object)null)
			{
				DiagnosticoAltarPlugin.Log.LogWarning((object)("[ALTAR]   desactivado (solo en esta sesión): " + e.Nombre));
				return;
			}
			WearNTear component = e.Objeto.GetComponent<WearNTear>();
			ZNetView component2 = e.Objeto.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null)
			{
				component.Remove(false);
			}
			else if ((Object)(object)component2 != (Object)null && component2.IsValid())
			{
				component2.ClaimOwnership();
				ZNetScene.instance.Destroy(e.Objeto);
			}
			DiagnosticoAltarPlugin.Log.LogWarning((object)("[ALTAR]   eliminado: " + e.Nombre + " en " + ((object)e.Objeto.transform.position/*cast due to .constrained prefix*/).ToString()));
		}

		private static void Avisar(long jugador, string texto)
		{
			DiagnosticoAltarPlugin.Log.LogInfo((object)("[ALTAR] Mensaje al jugador: " + texto.Replace("\n", " | ")));
			if (ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(jugador, "ShowMessage", new object[2] { 2, texto });
			}
		}

		private static string ClaveDe(OfferingBowl altar)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)altar).transform.position;
			return Mathf.RoundToInt(position.x) + "," + Mathf.RoundToInt(position.y) + "," + Mathf.RoundToInt(position.z);
		}

		private static string ListaDeNombres(List<Estorbo> plan)
		{
			List<string> list = plan.Select((Estorbo e) => e.Nombre).Distinct().ToList();
			string text = string.Join(", ", list.Take(5));
			if (list.Count <= 5)
			{
				return text;
			}
			return text + " y " + (list.Count - 5) + " más";
		}

		private static string NombreVisible(GameObject objeto)
		{
			Location componentInChildren = objeto.GetComponentInChildren<Location>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				string text = NombreDePrefab(((Component)componentInChildren).gameObject);
				(string, string)[] nombresDeLugares = NombresDeLugares;
				for (int i = 0; i < nombresDeLugares.Length; i++)
				{
					var (value, text2) = nombresDeLugares[i];
					if (text.StartsWith(value))
					{
						return text2 + " (lugar completo)";
					}
				}
				return "lugar " + text + " completo";
			}
			Piece component = objeto.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null && Localization.instance != null)
			{
				return Localization.instance.Localize(component.m_name);
			}
			return NombreDePrefab(objeto);
		}

		private static string NombreDePrefab(GameObject objeto)
		{
			return ((Object)objeto).name.Replace("(Clone)", "").Trim();
		}
	}
	[BepInPlugin("altairfernando.diagnosticoaltar", "DiagnosticoAltar", "1.0.0")]
	public class DiagnosticoAltarPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(OfferingBowl), "UseItem")]
		private static class OfferingBowl_UseItem_Diagnostico
		{
			[HarmonyPriority(800)]
			private static void Prefix(OfferingBowl __instance, Humanoid user, ItemData item)
			{
				try
				{
					Anotar(__instance, user, item);
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[ALTAR] Error al diagnosticar: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(OfferingBowl), "RPC_SpawnBoss")]
		private static class OfferingBowl_RPC_SpawnBoss_Jugador
		{
			private static void Prefix(long senderId)
			{
				_jugadorQueOfrece = senderId;
			}
		}

		[HarmonyPatch(typeof(OfferingBowl), "CanSpawnBoss")]
		private static class OfferingBowl_CanSpawnBoss_Diagnostico
		{
			private unsafe static void Postfix(OfferingBowl __instance, Vector3 point, ref Vector3 spawnPoint, ref bool __result)
			{
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				//IL_016f: Unknown result type (might be due to invalid IL or missing references)
				if (_reintentando)
				{
					return;
				}
				try
				{
					ManualLogSource log = Log;
					string[] obj = new string[8]
					{
						"[ALTAR] Buscando sitio para ",
						((Object)(object)__instance.m_bossPrefab != (Object)null) ? ((Object)__instance.m_bossPrefab).name : "?",
						" alrededor de ",
						null,
						null,
						null,
						null,
						null
					};
					Vector3 val = point;
					obj[3] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
					obj[4] = " (altar en ";
					obj[5] = ((object)((Component)__instance).transform.position/*cast due to .constrained prefix*/).ToString();
					obj[6] = "): ";
					obj[7] = (__result ? "ENCONTRADO" : "NINGUNO VALIDO");
					log.LogInfo((object)string.Concat(obj));
					Log.LogInfo((object)("[ALTAR] Reglas: radio max " + __instance.m_spawnBossMaxDistance + ", radio min " + __instance.m_spawnBossMinDistance + ", dif. altura max " + __instance.m_spawnBossMaxYDistance + ", radio libre " + __instance.m_spawnPointClearingRadius + ", comprobar suelo " + __instance.m_enableSolidHeightCheck + ", puntos fijos " + __instance.m_spawnPoints.Count));
					if (!__result)
					{
						AnalizarFallo(__instance, point);
						if (QuitarEstorbos.Value && EstorbosAltar.Resolver(__instance, point, _jugadorQueOfrece))
						{
							Reintentar(__instance, point, ref spawnPoint, ref __result);
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("[ALTAR] Error al diagnosticar el sitio: " + ex));
				}
			}

			private unsafe static void Reintentar(OfferingBowl altar, Vector3 point, ref Vector3 spawnPoint, ref bool resultado)
			{
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: Unknown result type (might be due to invalid IL or missing references)
				object[] array = new object[2]
				{
					point,
					Vector3.zero
				};
				_reintentando = true;
				try
				{
					resultado = (bool)AccessTools.Method(typeof(OfferingBowl), "CanSpawnBoss", (Type[])null, (Type[])null).Invoke(altar, array);
				}
				finally
				{
					_reintentando = false;
				}
				if (resultado)
				{
					spawnPoint = (Vector3)array[1];
					ManualLogSource log = Log;
					Vector3 val = spawnPoint;
					log.LogInfo((object)("[ALTAR] Reintento: ENCONTRADO en " + ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString() + ". El jefe va a aparecer."));
				}
				else
				{
					Log.LogWarning((object)"[ALTAR] Reintento: sigue sin haber sitio valido.");
				}
			}
		}

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> QuitarEstorbos;

		private static bool _parchesListados;

		private static long _jugadorQueOfrece;

		[ThreadStatic]
		private static bool _reintentando;

		private const int MuestrasDiagnostico = 60;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			QuitarEstorbos = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "QuitarEstorbos", true, "Si el jefe no puede aparecer porque hay algo encima del altar, avisa qué es; si se vuelve a ofrecer en menos de 5 minutos, lo elimina del mundo (las construcciones sueltan sus materiales y el contenido de los cofres).");
			new Harmony("altairfernando.diagnosticoaltar").PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)"DiagnosticoAltar cargado. Ofrece algo en un altar y busca [ALTAR] en el log.");
		}

		private static void AnalizarFallo(OfferingBowl altar, Vector3 point)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			float num5 = 0f;
			float num6 = float.MaxValue;
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			int mask = LayerMask.GetMask(new string[4] { "Default", "static_solid", "Default_small", "piece" });
			int mask2 = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });
			float num7 = default(float);
			for (int i = 0; i < 60; i++)
			{
				Vector2 val = Random.insideUnitCircle * altar.m_spawnBossMaxDistance;
				Vector3 val2 = point + new Vector3(val.x, 0f, val.y);
				if (!altar.m_enableSolidHeightCheck)
				{
					continue;
				}
				ZoneSystem.instance.GetSolidHeight(val2, ref num7, altar.m_getSolidHeightMargin);
				if (num7 < 0f)
				{
					num++;
					continue;
				}
				float num8 = Mathf.Abs(num7 - ((Component)altar).transform.position.y);
				if (num8 > altar.m_spawnBossMaxYDistance)
				{
					num2++;
					num5 = Mathf.Max(num5, num8);
					num6 = Mathf.Min(num6, num8);
					string key = QueTocaElRayo(val2, altar.m_getSolidHeightMargin, mask2);
					dictionary2[key] = ((!dictionary2.TryGetValue(key, out var value)) ? 1 : (value + 1));
				}
				else if (Vector3.Distance(val2, point) < altar.m_spawnBossMinDistance)
				{
					num3++;
				}
				else
				{
					if (!(altar.m_spawnPointClearingRadius > 0f))
					{
						continue;
					}
					val2.y = num7 + altar.m_spawnYOffset;
					Collider[] array = Physics.OverlapSphere(val2, altar.m_spawnPointClearingRadius, mask);
					if (array.Length != 0)
					{
						num4++;
						Collider[] array2 = array;
						foreach (Collider val3 in array2)
						{
							string key2 = ((Object)((Component)val3).transform.root).name + " (capa " + LayerMask.LayerToName(((Component)val3).gameObject.layer) + ")";
							dictionary[key2] = ((!dictionary.TryGetValue(key2, out var value2)) ? 1 : (value2 + 1));
						}
					}
				}
			}
			Log.LogWarning((object)("[ALTAR] De " + 60 + " puntos: sin suelo " + num + ", demasiada diferencia de altura " + num2 + " (peor " + num5.ToString("0.0") + " m), demasiado cerca " + num3 + ", bloqueados por objetos " + num4));
			if (num2 > 0)
			{
				Log.LogWarning((object)("[ALTAR] Diferencia de altura entre " + num6.ToString("0.0") + " y " + num5.ToString("0.0") + " m"));
			}
			foreach (KeyValuePair<string, int> item in dictionary2.OrderByDescending((KeyValuePair<string, int> x) => x.Value).Take(15))
			{
				Log.LogWarning((object)("[ALTAR]   el suelo lo marca: " + item.Key + " en " + item.Value + " puntos"));
			}
			foreach (KeyValuePair<string, int> item2 in dictionary.OrderByDescending((KeyValuePair<string, int> x) => x.Value).Take(15))
			{
				Log.LogWarning((object)("[ALTAR]   bloquea: " + item2.Key + " en " + item2.Value + " puntos"));
			}
		}

		private static string QueTocaElRayo(Vector3 p, int margen, int mascara)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (!Physics.Raycast(p + Vector3.up * (float)margen, Vector3.down, ref val, 2000f, mascara))
			{
				return "(nada)";
			}
			Collider collider = ((RaycastHit)(ref val)).collider;
			return ((Object)((Component)collider).transform.root).name + " / " + ((Object)collider).name + " (capa " + LayerMask.LayerToName(((Component)collider).gameObject.layer) + ", y " + ((RaycastHit)(ref val)).point.y.ToString("0") + ")";
		}

		private static void Anotar(OfferingBowl altar, Humanoid user, ItemData item)
		{
			Log.LogInfo((object)("[ALTAR] ===== Ofrenda en " + altar.m_name + " (objeto " + RutaDe(((Component)altar).transform) + ")"));
			Log.LogInfo((object)("[ALTAR] Usa soportes de objetos: " + altar.m_useItemStands));
			if ((Object)(object)altar.m_bossItem == (Object)null)
			{
				Log.LogWarning((object)"[ALTAR] El altar NO tiene ofrenda configurada (m_bossItem es null).");
			}
			else
			{
				SharedData val = altar.m_bossItem.m_itemData?.m_shared;
				Log.LogInfo((object)("[ALTAR] Pide: prefab '" + ((Object)altar.m_bossItem).name + "', nombre interno '" + ((val != null) ? val.m_name : "(sin datos)") + "', cantidad " + altar.m_bossItems));
			}
			Log.LogInfo((object)("[ALTAR] Jefe que invoca: " + (((Object)(object)altar.m_bossPrefab != (Object)null) ? ((Object)altar.m_bossPrefab).name : "(ninguno)")));
			if (item == null)
			{
				Log.LogWarning((object)"[ALTAR] Se ofreció un objeto nulo.");
				return;
			}
			SharedData ofrecido = item.m_shared;
			Log.LogInfo((object)("[ALTAR] Ofrecido: prefab '" + (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : "(sin prefab)") + "', nombre interno '" + ofrecido.m_name + "', cantidad en la casilla " + item.m_stack + ", nivel de mundo " + item.m_worldLevel));
			if ((Object)(object)altar.m_bossItem != (Object)null && altar.m_bossItem.m_itemData != null)
			{
				SharedData shared = altar.m_bossItem.m_itemData.m_shared;
				Log.LogInfo((object)("[ALTAR] ¿Mismo nombre interno?: " + (ofrecido.m_name == shared.m_name) + " | ¿Mismos datos compartidos?: " + (ofrecido == shared)));
				if ((Object)(object)user != (Object)null)
				{
					Log.LogInfo((object)("[ALTAR] En tu inventario hay " + user.GetInventory().CountItems(shared.m_name, -1, true) + " de lo que pide el altar."));
				}
			}
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				List<string> list = (from go in ObjectDB.instance.m_items
					where (Object)(object)go != (Object)null
					select go.GetComponent<ItemDrop>() into d
					where (Object)(object)d != (Object)null && d.m_itemData?.m_shared != null && (d.m_itemData.m_shared.m_name == ofrecido.m_name || ((Object)(object)altar.m_bossItem != (Object)null && d.m_itemData.m_shared.m_name == altar.m_bossItem.m_itemData?.m_shared?.m_name))
					select ((Object)d).name + " = " + d.m_itemData.m_shared.m_name).ToList();
				Log.LogInfo((object)("[ALTAR] Objetos en ObjectDB con esos nombres (" + list.Count + "): " + string.Join(" ; ", list)));
			}
			if (!_parchesListados)
			{
				_parchesListados = true;
				ListarParches(AccessTools.Method(typeof(OfferingBowl), "UseItem", (Type[])null, (Type[])null));
				ListarParches(AccessTools.Method(typeof(Humanoid), "UseItem", (Type[])null, (Type[])null));
				ListarParches(AccessTools.Method(typeof(Player), "UseHotbarItem", (Type[])null, (Type[])null));
			}
		}

		private static void ListarParches(MethodBase metodo)
		{
			if (metodo == null)
			{
				return;
			}
			Patches patchInfo = Harmony.GetPatchInfo(metodo);
			string text = metodo.DeclaringType.Name + "." + metodo.Name;
			if (patchInfo == null)
			{
				Log.LogInfo((object)("[ALTAR] Nadie modifica " + text));
				return;
			}
			foreach (Patch prefix in patchInfo.Prefixes)
			{
				Log.LogInfo((object)("[ALTAR] " + text + " prefix de " + prefix.owner + " (" + prefix.PatchMethod.DeclaringType?.ToString() + ")"));
			}
			foreach (Patch postfix in patchInfo.Postfixes)
			{
				Log.LogInfo((object)("[ALTAR] " + text + " postfix de " + postfix.owner + " (" + postfix.PatchMethod.DeclaringType?.ToString() + ")"));
			}
			foreach (Patch transpiler in patchInfo.Transpilers)
			{
				Log.LogInfo((object)("[ALTAR] " + text + " transpiler de " + transpiler.owner + " (" + transpiler.PatchMethod.DeclaringType?.ToString() + ")"));
			}
			foreach (Patch finalizer in patchInfo.Finalizers)
			{
				Log.LogInfo((object)("[ALTAR] " + text + " finalizer de " + finalizer.owner + " (" + finalizer.PatchMethod.DeclaringType?.ToString() + ")"));
			}
		}

		private static string RutaDe(Transform t)
		{
			string text = ((Object)t).name;
			while ((Object)(object)t.parent != (Object)null)
			{
				t = t.parent;
				text = ((Object)t).name + "/" + text;
			}
			return text;
		}
	}
}