Decompiled source of Huevitos3P Thunderstore v2.8.0

BepInEx/plugins/HuevitoRey/HuevitoRey.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ModsPlus;
using Photon.Pun;
using UnboundLib;
using UnboundLib.Cards;
using UnboundLib.GameModes;
using UnityEngine;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HuevitoRey;

internal sealed class ChaosDirector : MonoBehaviour
{
	private sealed class BreakableAnchor : MonoBehaviour
	{
		private bool _broken;

		private void OnCollisionEnter2D(Collision2D collision)
		{
			Break();
		}

		private void OnTriggerEnter2D(Collider2D collider)
		{
			Break();
		}

		private void Break()
		{
			if (!_broken)
			{
				_broken = true;
				((Component)this).gameObject.SetActive(false);
			}
		}
	}

	private const string EventConfig = "HuevitoRey_Config";

	private const string EventRound = "HuevitoRey_Round";

	private const string EventSnapshot = "HuevitoRey_Snapshot";

	private const string EventRequestSnapshot = "HuevitoRey_RequestSnapshot";

	private const string EventVote = "HuevitoRey_Vote";

	private static ChaosDirector _instance;

	private ManualLogSource _log;

	private MatchConfig _config;

	private RoundState _roundState = new RoundState();

	private readonly Dictionary<int, int> _wins = new Dictionary<int, int>();

	private readonly Dictionary<int, string> _votes = new Dictionary<int, string>();

	private readonly Dictionary<GameObject, Vector3> _originalScales = new Dictionary<GameObject, Vector3>();

	private readonly Dictionary<GameObject, Color[]> _originalColors = new Dictionary<GameObject, Color[]>();

	private readonly Dictionary<GameObject, Vector3> _platformOrigins = new Dictionary<GameObject, Vector3>();

	private readonly Dictionary<GameObject, bool> _breakableActive = new Dictionary<GameObject, bool>();

	private readonly Dictionary<int, float> _portalCooldown = new Dictionary<int, float>();

	private readonly List<GameObject> _platforms = new List<GameObject>();

	private readonly List<GameObject> _breakables = new List<GameObject>();

	private readonly List<GameObject> _portalsA = new List<GameObject>();

	private readonly List<GameObject> _portalsB = new List<GameObject>();

	private ConfigEntry<KeyCode> _menuKey;

	private ConfigEntry<int> _defaultMaxModifiers;

	private ConfigEntry<int> _defaultIntensity;

	private ConfigEntry<bool> _defaultVoteMode;

	private ConfigEntry<int> _defaultSeed;

	private ConfigEntry<bool> _autoSpawnCompatibleAnchors;

	private ConfigEntry<bool> _debugSelfTest;

	private bool _menuOpen;

	private bool[] _draft = new bool[ModifierCatalog.All.Length];

	private int _draftIntensity = 1;

	private int _draftMaxActive = 4;

	private bool _draftVoteMode;

	private Rect _window = new Rect(30f, 90f, 470f, 700f);

	private string _banner = string.Empty;

	private float _bannerUntil;

	private float _lastSnapshotRequest;

	private float _lastHostSnapshot;

	private float _roundStartedAt;

	private Vector2 _baseGravity;

	private float _baseCameraSize;

	private bool _baseCameraCaptured;

	private bool _roundActive;

	private int _lastRecordedRound = -1;

	private string _lastAward = string.Empty;

	private GameObject _compatibleKit;

	private Sprite _solidSprite;

	private bool _cardsPlusPatched;

	private bool _selfTestRequested;

	private bool _selfTestStarted;

	public static float ProjectileScaleMultiplier { get; private set; }

	private bool IsHost
	{
		get
		{
			if (!PhotonNetwork.OfflineMode && PhotonNetwork.IsConnected)
			{
				return PhotonNetwork.IsMasterClient;
			}
			return true;
		}
	}

	private bool CanRaiseNetworkEvent
	{
		get
		{
			if (PhotonNetwork.IsConnected)
			{
				return PhotonNetwork.InRoom;
			}
			return false;
		}
	}

	private Sprite SolidSprite
	{
		get
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0022: 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)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_solidSprite != (Object)null)
			{
				return _solidSprite;
			}
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, Color.white);
			val.Apply();
			_solidSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f);
			return _solidSprite;
		}
	}

	public static void Create(ManualLogSource log, BaseUnityPlugin plugin)
	{
		if (!((Object)(object)_instance != (Object)null))
		{
			_instance = ((Component)plugin).gameObject.AddComponent<ChaosDirector>();
			_instance._log = log;
			_instance.Configure(plugin.Config);
			Object.DontDestroyOnLoad((Object)(object)((Component)_instance).gameObject);
		}
	}

	private void Configure(ConfigFile configFile)
	{
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Expected O, but got Unknown
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Expected O, but got Unknown
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Expected O, but got Unknown
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Expected O, but got Unknown
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_024f: Expected O, but got Unknown
		_menuKey = configFile.Bind<KeyCode>("Menu", "OpenKey", (KeyCode)289, "Tecla para abrir el selector antes de la partida.");
		_defaultMaxModifiers = configFile.Bind<int>("Menu", "DefaultMaxModifiers", 4, "Cantidad maxima de modificaciones activas.");
		_defaultIntensity = configFile.Bind<int>("Menu", "DefaultIntensity", 1, "Intensidad por defecto: 1, 2 o 3.");
		_defaultVoteMode = configFile.Bind<bool>("Menu", "DefaultVoteMode", false, "Deja preparada la votacion de reglas.");
		_defaultSeed = configFile.Bind<int>("Match", "DefaultSeed", 0, "Semilla; 0 usa una nueva semilla por partida.");
		_autoSpawnCompatibleAnchors = configFile.Bind<bool>("Map", "AutoSpawnCompatibleAnchors", true, "Crea anclas propias del mod para las reglas de mapa; no modifica colliders externos.");
		_debugSelfTest = configFile.Bind<bool>("Debug", "SelfTest", false, "Solo QA: ejecuta las diez reglas y las restaura al iniciar.");
		_draftMaxActive = Clamp(_defaultMaxModifiers.Value, 1, ModifierCatalog.All.Length);
		_draftIntensity = Clamp(_defaultIntensity.Value, 1, 3);
		_draftVoteMode = _defaultVoteMode.Value;
		_baseGravity = Physics2D.gravity;
		_selfTestRequested = _debugSelfTest.Value || File.Exists(Path.Combine(Paths.ConfigPath, "huevito-self-test.flag")) || Array.Exists(Environment.GetCommandLineArgs(), (string value) => string.Equals(value, "-huevito-self-test", StringComparison.OrdinalIgnoreCase));
		if (_selfTestRequested && _log != null)
		{
			_log.LogInfo((object)"SELFTEST requested.");
		}
		PatchExternalCompatibility();
		if (_selfTestRequested)
		{
			_selfTestStarted = true;
			string text = RunSelfTestNow();
			if (_log != null)
			{
				if (string.IsNullOrEmpty(text))
				{
					_log.LogInfo((object)"SELFTEST PASS: diez modificadores ejecutados y restaurados en la copia aislada.");
				}
				else
				{
					_log.LogError((object)("SELFTEST FAIL: " + text));
				}
			}
		}
		NetworkingManager.RegisterEvent("HuevitoRey_Config", new PhotonEvent(OnConfigEvent));
		NetworkingManager.RegisterEvent("HuevitoRey_Round", new PhotonEvent(OnRoundEvent));
		NetworkingManager.RegisterEvent("HuevitoRey_Snapshot", new PhotonEvent(OnSnapshotEvent));
		NetworkingManager.RegisterEvent("HuevitoRey_RequestSnapshot", new PhotonEvent(OnSnapshotRequest));
		NetworkingManager.RegisterEvent("HuevitoRey_Vote", new PhotonEvent(OnVoteEvent));
		GameModeManager.AddHook("GameStart", (Func<IGameModeHandler, IEnumerator>)OnGameStart);
		GameModeManager.AddHook("GameEnd", (Func<IGameModeHandler, IEnumerator>)OnGameEnd);
		GameModeManager.AddHook("PointEnd", (Func<IGameModeHandler, IEnumerator>)OnPointEnd);
		GameModeManager.AddHook("RoundStart", (Func<IGameModeHandler, IEnumerator>)OnRoundStart);
		GameModeManager.AddHook("RoundEnd", (Func<IGameModeHandler, IEnumerator>)OnRoundEnd);
		ShowBanner("Huevito Rey listo. F8 para elegir las reglas antes de jugar.", 8f);
	}

	private void Update()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		if (!_cardsPlusPatched)
		{
			PatchExternalCompatibility();
		}
		if (_selfTestRequested && !_selfTestStarted)
		{
			_selfTestStarted = true;
			((MonoBehaviour)this).StartCoroutine(RunSelfTest());
		}
		if (Input.GetKeyDown(_menuKey.Value))
		{
			ToggleMenu("F8");
		}
		if (_config != null && _roundState.Ready && _roundActive)
		{
			EnsureCompatibleAnchors();
			UpdateMovingPlatforms();
			UpdatePortals();
			UpdateShrinkingArena();
		}
		if (Time.time - _lastSnapshotRequest > 5f)
		{
			_lastSnapshotRequest = Time.time;
			if (!IsHost)
			{
				NetworkingManager.RaiseEvent("HuevitoRey_RequestSnapshot", new object[0]);
			}
		}
		if (IsHost && _config != null && Time.time - _lastHostSnapshot > 5f)
		{
			_lastHostSnapshot = Time.time;
			BroadcastSnapshot();
		}
	}

	private IEnumerator RunSelfTest()
	{
		yield return (object)new WaitForSeconds(1f);
		string error = RunSelfTestNow();
		if (string.IsNullOrEmpty(error))
		{
			if (_log != null)
			{
				_log.LogInfo((object)"SELFTEST PASS: diez modificadores ejecutados y restaurados en la copia aislada.");
			}
		}
		else if (_log != null)
		{
			_log.LogError((object)("SELFTEST FAIL: " + error));
		}
	}

	private string RunSelfTestNow()
	{
		try
		{
			_config = new MatchConfig
			{
				Seed = 2600,
				Intensity = 3,
				MaxActive = ModifierCatalog.All.Length,
				VoteMode = true,
				Active = (string[])ModifierCatalog.All.Clone()
			};
			_roundState = new RoundState
			{
				RoundNumber = 0
			};
			EnsureCompatibleAnchors();
			_roundState = BuildRoundState();
			ApplyRoundState();
			UpdateMovingPlatforms();
			UpdatePortals();
			UpdateShrinkingArena();
			ResetRoundVisuals();
			DestroyCompatibleAnchors();
			return string.Empty;
		}
		catch (Exception ex)
		{
			DestroyCompatibleAnchors();
			return ex.ToString();
		}
	}

	private void OnGUI()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//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)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Expected O, but got Unknown
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		string text = (_menuOpen ? "Cerrar reglas (F8)" : "Reglas de la partida (F8)");
		if (GUI.Button(new Rect((float)Screen.width - 320f, 20f, 300f, 38f), text))
		{
			ToggleMenu("botón");
		}
		if (_menuOpen)
		{
			_window = GUI.Window(78123, _window, new WindowFunction(DrawMenu), "Huevito Rey — reglas de la partida");
		}
		if (!string.IsNullOrEmpty(_banner) && Time.time < _bannerUntil)
		{
			GUIStyle val = new GUIStyle(GUI.skin.box);
			val.fontSize = 16;
			val.normal.textColor = Color.white;
			GUI.Box(new Rect(20f, (float)Screen.height - 75f, (float)Screen.width - 40f, 48f), _banner, val);
		}
	}

	private void ToggleMenu(string source)
	{
		_menuOpen = !_menuOpen;
		if (_menuOpen)
		{
			LoadDraft();
		}
		if (_log != null)
		{
			_log.LogInfo((object)("Selector " + source + " " + (_menuOpen ? "abierto" : "cerrado") + "."));
		}
	}

	private void DrawMenu(int id)
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_040e: Unknown result type (might be due to invalid IL or missing references)
		GUIStyle val = new GUIStyle(GUI.skin.label);
		val.wordWrap = true;
		val.fontSize = 14;
		GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label(IsHost ? "El anfitrion decide y sincroniza. Abre esto antes de iniciar la partida." : "Solo el anfitrion puede aplicar cambios; esta vista muestra tu estado local.", val, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Space(8f);
		GUI.enabled = IsHost;
		for (int i = 0; i < ModifierCatalog.All.Length; i++)
		{
			_draft[i] = GUILayout.Toggle(_draft[i], ModifierCatalog.Label(ModifierCatalog.All[i]), (GUILayoutOption[])(object)new GUILayoutOption[0]);
		}
		GUILayout.Space(8f);
		GUILayout.Label("Intensidad: " + _draftIntensity + "   (1 suave / 2 caotica / 3 ridicula)", (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) }))
		{
			_draftIntensity = Clamp(_draftIntensity - 1, 1, 3);
		}
		if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) }))
		{
			_draftIntensity = Clamp(_draftIntensity + 1, 1, 3);
		}
		GUILayout.Label("Maximo de modificaciones: " + _draftMaxActive, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		if (GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) }))
		{
			_draftMaxActive = Clamp(_draftMaxActive - 1, 1, ModifierCatalog.All.Length);
		}
		if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(35f) }))
		{
			_draftMaxActive = Clamp(_draftMaxActive + 1, 1, ModifierCatalog.All.Length);
		}
		GUILayout.EndHorizontal();
		GUI.enabled = true;
		GUILayout.Space(10f);
		_draftVoteMode = GUILayout.Toggle(_draftVoteMode, "Permitir votacion de reglas entre jugadores", (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label("Las plataformas, objetos, portales y arena usan objetos propios del mod.", val, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUI.enabled = IsHost;
		if (GUILayout.Button("Aplicar y sincronizar", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
		{
			ApplyDraft();
		}
		GUI.enabled = true;
		if (GUILayout.Button("Cerrar", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
		{
			_menuOpen = false;
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(8f);
		if (_config != null)
		{
			GUILayout.Label("Estado: " + _config.Active.Length + " modificaciones | semilla " + _config.Seed + " | round " + _roundState.RoundNumber, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			GUILayout.Label("Ahora: " + DescribeRound(), (GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (_config.VoteMode && _config.Has("rule_vote"))
			{
				GUILayout.Space(6f);
				GUILayout.Label("Vota la regla del siguiente round:", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
				if (GUILayout.Button("Gravedad", (GUILayoutOption[])(object)new GUILayoutOption[0]))
				{
					SubmitVote("heavy_gravity");
				}
				if (GUILayout.Button("Pequeños", (GUILayoutOption[])(object)new GUILayoutOption[0]))
				{
					SubmitVote("tiny_heroes");
				}
				if (GUILayout.Button("Gigantes", (GUILayoutOption[])(object)new GUILayoutOption[0]))
				{
					SubmitVote("giant_heroes");
				}
				if (GUILayout.Button("Huevitos", (GUILayoutOption[])(object)new GUILayoutOption[0]))
				{
					SubmitVote("no_egg_escape");
				}
				GUILayout.EndHorizontal();
			}
		}
		GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		GUILayout.EndVertical();
	}

	private void LoadDraft()
	{
		if (_config == null)
		{
			_draftMaxActive = Clamp(_defaultMaxModifiers.Value, 1, ModifierCatalog.All.Length);
			_draftIntensity = Clamp(_defaultIntensity.Value, 1, 3);
			_draftVoteMode = _defaultVoteMode.Value;
			for (int i = 0; i < _draft.Length; i++)
			{
				_draft[i] = false;
			}
		}
		else
		{
			_draftMaxActive = _config.MaxActive;
			_draftIntensity = _config.Intensity;
			_draftVoteMode = _config.VoteMode;
			for (int j = 0; j < ModifierCatalog.All.Length; j++)
			{
				_draft[j] = _config.Has(ModifierCatalog.All[j]);
			}
		}
	}

	private void ApplyDraft()
	{
		if (!IsHost)
		{
			return;
		}
		List<string> list = new List<string>();
		for (int i = 0; i < ModifierCatalog.All.Length; i++)
		{
			if (_draft[i] && list.Count < _draftMaxActive)
			{
				list.Add(ModifierCatalog.All[i]);
			}
		}
		_config = new MatchConfig();
		_config.Seed = (int)((_defaultSeed.Value == 0) ? (DateTime.UtcNow.Ticks & 0x7FFFFFFF) : _defaultSeed.Value);
		_config.Intensity = Clamp(_draftIntensity, 1, 3);
		_config.MaxActive = Clamp(_draftMaxActive, 1, ModifierCatalog.All.Length);
		_config.VoteMode = _draftVoteMode;
		_config.Active = list.ToArray();
		_roundState = new RoundState();
		_wins.Clear();
		_lastRecordedRound = -1;
		BroadcastSnapshot();
		ShowBanner("Reglas sincronizadas para todos. Ya pueden iniciar la partida.", 6f);
	}

	private void OnConfigEvent(object[] data)
	{
		_config = MatchConfig.FromNetwork(data, 0);
		ShowBanner("Reglas recibidas: " + _config.Active.Length + " modificaciones.", 4f);
	}

	private void OnRoundEvent(object[] data)
	{
		if (data != null && data.Length >= 8)
		{
			_roundState = new RoundState
			{
				RoundNumber = Convert.ToInt32(data[0]),
				EventId = Convert.ToString(data[1]),
				RuleId = Convert.ToString(data[2]),
				PunishmentTarget = Convert.ToInt32(data[3]),
				RivalA = Convert.ToInt32(data[4]),
				RivalB = Convert.ToInt32(data[5]),
				Champion = Convert.ToInt32(data[6]),
				BreakableIndex = Convert.ToInt32(data[7]),
				Ready = true
			};
			ApplyRoundState();
		}
	}

	private void OnSnapshotEvent(object[] data)
	{
		if (data != null && data.Length >= 14)
		{
			_config = MatchConfig.FromNetwork(data, 0);
			OnRoundEvent(new object[8]
			{
				data[5],
				data[6],
				data[7],
				data[8],
				data[9],
				data[10],
				data[11],
				data[12]
			});
			_lastAward = Convert.ToString(data[13]);
			if (data.Length > 14)
			{
				DecodeWins(Convert.ToString(data[14]));
			}
			_roundActive = data.Length <= 15 || Convert.ToBoolean(data[15]);
			if (!_roundActive)
			{
				ResetRoundVisuals();
			}
		}
	}

	private void OnSnapshotRequest(object[] data)
	{
		if (IsHost && _config != null)
		{
			BroadcastSnapshot();
		}
	}

	private void OnVoteEvent(object[] data)
	{
		if (IsHost && data != null && data.Length >= 2 && _config != null && _config.VoteMode)
		{
			int key = Convert.ToInt32(data[0]);
			string text = Convert.ToString(data[1]);
			_votes[key] = text;
			ShowBanner("Voto recibido para " + text + ".", 3f);
		}
	}

	private void SubmitVote(string rule)
	{
		if (_config != null && _config.VoteMode)
		{
			int num = ((PhotonNetwork.LocalPlayer != null) ? PhotonNetwork.LocalPlayer.ActorNumber : 0);
			if (IsHost)
			{
				_votes[num] = rule;
			}
			else if (CanRaiseNetworkEvent)
			{
				NetworkingManager.RaiseEvent("HuevitoRey_Vote", new object[2] { num, rule });
			}
			ShowBanner("Voto guardado: " + rule + ".", 3f);
		}
	}

	private void BroadcastRound()
	{
		if (CanRaiseNetworkEvent)
		{
			NetworkingManager.RaiseEvent("HuevitoRey_Round", new object[8] { _roundState.RoundNumber, _roundState.EventId, _roundState.RuleId, _roundState.PunishmentTarget, _roundState.RivalA, _roundState.RivalB, _roundState.Champion, _roundState.BreakableIndex });
		}
	}

	private void BroadcastSnapshot()
	{
		if (_config != null && CanRaiseNetworkEvent)
		{
			NetworkingManager.RaiseEvent("HuevitoRey_Snapshot", new object[16]
			{
				_config.Seed,
				_config.EncodeActive(),
				_config.Intensity,
				_config.MaxActive,
				_config.VoteMode,
				_roundState.RoundNumber,
				_roundState.EventId,
				_roundState.RuleId,
				_roundState.PunishmentTarget,
				_roundState.RivalA,
				_roundState.RivalB,
				_roundState.Champion,
				_roundState.BreakableIndex,
				_lastAward,
				EncodeWins(),
				_roundActive
			});
		}
	}

	private IEnumerator OnGameStart(IGameModeHandler handler)
	{
		if (_config == null && IsHost)
		{
			_menuOpen = true;
			LoadDraft();
			ShowBanner("Elige las modificaciones con F8 antes de seguir.", 6f);
		}
		yield break;
	}

	private IEnumerator OnGameEnd(IGameModeHandler handler)
	{
		_roundActive = false;
		ResetRoundVisuals();
		_roundState = new RoundState();
		_wins.Clear();
		_lastRecordedRound = -1;
		DestroyCompatibleAnchors();
		yield break;
	}

	private IEnumerator OnPointEnd(IGameModeHandler handler)
	{
		if (IsHost && _config != null)
		{
			RecordWinner();
		}
		yield break;
	}

	private IEnumerator OnRoundStart(IGameModeHandler handler)
	{
		if (_config != null)
		{
			_roundActive = false;
			ResetRoundVisuals();
			EnsureCompatibleAnchors();
			_roundStartedAt = Time.time;
			if (IsHost)
			{
				_roundState = BuildRoundState();
				BroadcastRound();
			}
			float deadline = Time.time + 2f;
			while (!_roundState.Ready && Time.time < deadline)
			{
				yield return null;
			}
			if (!_roundState.Ready)
			{
				_roundState = BuildRoundState();
			}
			ApplyRoundState();
			_roundActive = true;
		}
	}

	private IEnumerator OnRoundEnd(IGameModeHandler handler)
	{
		_roundActive = false;
		if (_config != null && _config.Has("absurd_awards"))
		{
			_lastAward = BuildAward();
			ShowBanner(_lastAward, 8f);
		}
		ResetRoundVisuals();
		if (IsHost && _config != null)
		{
			BroadcastSnapshot();
		}
		yield break;
	}

	private RoundState BuildRoundState()
	{
		RoundState roundState = new RoundState();
		roundState.RoundNumber = _roundState.RoundNumber + 1;
		roundState.Champion = FindChampion();
		Random random = new Random((_config.Seed ^ (roundState.RoundNumber * 7919)) + _config.Intensity * 31);
		if (_config.Has("random_events"))
		{
			string[] array = new string[5] { "low_gravity", "moon_jump", "giant_players", "tiny_players", "egg_storm" };
			roundState.EventId = array[random.Next(array.Length)];
		}
		if (_config.Has("rule_vote"))
		{
			string[] array2 = new string[4] { "heavy_gravity", "tiny_heroes", "giant_heroes", "no_egg_escape" };
			roundState.RuleId = WinnerVote(array2);
			if (string.IsNullOrEmpty(roundState.RuleId))
			{
				roundState.RuleId = array2[random.Next(array2.Length)];
			}
			_votes.Clear();
		}
		List<Player> list = CurrentPlayers();
		if (_config.Has("punishment_roulette") && list.Count > 0)
		{
			roundState.PunishmentTarget = list[random.Next(list.Count)].playerID;
		}
		if (_config.Has("rivalries") && list.Count > 1)
		{
			int num = random.Next(list.Count);
			int num2 = random.Next(list.Count - 1);
			if (num2 >= num)
			{
				num2++;
			}
			roundState.RivalA = list[num].playerID;
			roundState.RivalB = list[num2].playerID;
		}
		roundState.BreakableIndex = ChooseBreakableIndex(random);
		roundState.Ready = true;
		return roundState;
	}

	private string WinnerVote(string[] rules)
	{
		Dictionary<string, int> dictionary = new Dictionary<string, int>();
		foreach (KeyValuePair<int, string> vote in _votes)
		{
			for (int i = 0; i < rules.Length; i++)
			{
				if (string.Equals(vote.Value, rules[i], StringComparison.OrdinalIgnoreCase))
				{
					dictionary[rules[i]] = ((!dictionary.ContainsKey(rules[i])) ? 1 : (dictionary[rules[i]] + 1));
				}
			}
		}
		string result = string.Empty;
		int num = 0;
		foreach (string text in rules)
		{
			int num2 = (dictionary.ContainsKey(text) ? dictionary[text] : 0);
			if (num2 > num)
			{
				num = num2;
				result = text;
			}
		}
		return result;
	}

	private void ApplyRoundState()
	{
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		if (_roundState.Ready)
		{
			ProjectileScaleMultiplier = 1f;
			switch (_roundState.EventId)
			{
			case "low_gravity":
				Physics2D.gravity = _baseGravity * 0.45f;
				break;
			case "moon_jump":
				Physics2D.gravity = _baseGravity * 0.18f;
				break;
			case "giant_players":
				ScaleAllPlayers(1.35f);
				break;
			case "tiny_players":
				ScaleAllPlayers(0.72f);
				break;
			case "egg_storm":
				ProjectileScaleMultiplier = 1.8f;
				break;
			}
			ApplyRule(_roundState.RuleId);
			if (_config != null && _config.Has("champion_target"))
			{
				ApplyChampionTarget(_roundState.Champion);
			}
			if (_config != null && _config.Has("rivalries"))
			{
				ApplyRivalry(_roundState.RivalA, _roundState.RivalB);
			}
			if (_config != null && _config.Has("punishment_roulette"))
			{
				ApplyPunishment(_roundState.PunishmentTarget);
			}
			if (_config != null && _config.Has("destructible_objects"))
			{
				ApplyBreakable(_roundState.BreakableIndex);
			}
			if (_config != null && _config.Has("moving_platforms"))
			{
				CachePlatforms();
			}
			if (_config != null && _config.Has("unstable_portals"))
			{
				CachePortals();
			}
			ShowBanner("Round " + _roundState.RoundNumber + ": " + DescribeRound(), 8f);
		}
	}

	private void ApplyRule(string rule)
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		switch (rule)
		{
		case "heavy_gravity":
			Physics2D.gravity = _baseGravity * 1.75f;
			break;
		case "tiny_heroes":
			ScaleAllPlayers(0.78f);
			break;
		case "giant_heroes":
			ScaleAllPlayers(1.25f);
			break;
		case "no_egg_escape":
			ProjectileScaleMultiplier = 1.5f;
			break;
		}
	}

	private void ApplyChampionTarget(int id)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		Player val = FindPlayer(id);
		if (!((Object)(object)val == (Object)null))
		{
			RememberAppearance(((Component)val).gameObject);
			((Component)val).transform.localScale = ((Component)val).transform.localScale * 1.12f;
			Tint(((Component)val).gameObject, new Color(1f, 0.82f, 0.12f, 1f));
		}
	}

	private void ApplyRivalry(int a, int b)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		Player val = FindPlayer(a);
		Player val2 = FindPlayer(b);
		if ((Object)(object)val != (Object)null)
		{
			Tint(((Component)val).gameObject, new Color(0.85f, 0.2f, 1f, 1f));
		}
		if ((Object)(object)val2 != (Object)null)
		{
			Tint(((Component)val2).gameObject, new Color(0.15f, 0.9f, 1f, 1f));
		}
	}

	private void ApplyPunishment(int id)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		Player val = FindPlayer(id);
		if (!((Object)(object)val == (Object)null))
		{
			RememberAppearance(((Component)val).gameObject);
			((Component)val).transform.localScale = ((Component)val).transform.localScale * 0.78f;
			Tint(((Component)val).gameObject, new Color(1f, 0.3f, 0.3f, 1f));
		}
	}

	private void ResetRoundVisuals()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: 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)
		Physics2D.gravity = _baseGravity;
		ProjectileScaleMultiplier = 1f;
		foreach (KeyValuePair<GameObject, Vector3> originalScale in _originalScales)
		{
			if ((Object)(object)originalScale.Key != (Object)null)
			{
				originalScale.Key.transform.localScale = originalScale.Value;
			}
		}
		foreach (KeyValuePair<GameObject, Color[]> originalColor in _originalColors)
		{
			if (!((Object)(object)originalColor.Key == (Object)null))
			{
				SpriteRenderer[] componentsInChildren = originalColor.Key.GetComponentsInChildren<SpriteRenderer>(true);
				for (int i = 0; i < componentsInChildren.Length && i < originalColor.Value.Length; i++)
				{
					componentsInChildren[i].color = originalColor.Value[i];
				}
			}
		}
		_originalScales.Clear();
		_originalColors.Clear();
		RestoreMapObjects();
		if (_baseCameraCaptured && (Object)(object)Camera.main != (Object)null)
		{
			Camera.main.orthographicSize = _baseCameraSize;
		}
		_baseCameraCaptured = false;
	}

	private void RememberAppearance(GameObject target)
	{
		//IL_0025: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)target == (Object)null)
		{
			return;
		}
		if (!_originalScales.ContainsKey(target))
		{
			_originalScales[target] = target.transform.localScale;
		}
		if (!_originalColors.ContainsKey(target))
		{
			SpriteRenderer[] componentsInChildren = target.GetComponentsInChildren<SpriteRenderer>(true);
			Color[] array = (Color[])(object)new Color[componentsInChildren.Length];
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				ref Color reference = ref array[i];
				reference = componentsInChildren[i].color;
			}
			_originalColors[target] = array;
		}
	}

	private void ScaleAllPlayers(float amount)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		List<Player> list = CurrentPlayers();
		for (int i = 0; i < list.Count; i++)
		{
			RememberAppearance(((Component)list[i]).gameObject);
			((Component)list[i]).transform.localScale = ((Component)list[i]).transform.localScale * amount;
		}
	}

	private void Tint(GameObject target, Color color)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		RememberAppearance(target);
		SpriteRenderer[] componentsInChildren = target.GetComponentsInChildren<SpriteRenderer>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			componentsInChildren[i].color = Color.Lerp(componentsInChildren[i].color, color, 0.7f);
		}
	}

	private void CachePlatforms()
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		_platforms.Clear();
		GameObject[] array = Object.FindObjectsOfType<GameObject>();
		foreach (GameObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && val.activeInHierarchy && ((Object)val).name.IndexOf("HuevitoPlatform", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				if (!_platformOrigins.ContainsKey(val))
				{
					_platformOrigins[val] = val.transform.position;
				}
				_platforms.Add(val);
			}
		}
		if (_platforms.Count == 0)
		{
			ShowBanner("Plataformas moviles: este mapa no tiene anclas HuevitoPlatform.", 5f);
		}
	}

	private void EnsureCompatibleAnchors()
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Expected O, but got Unknown
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		if (_autoSpawnCompatibleAnchors != null && _autoSpawnCompatibleAnchors.Value && _config != null && (_config.Has("moving_platforms") || _config.Has("destructible_objects") || _config.Has("unstable_portals")) && !((Object)(object)_compatibleKit != (Object)null))
		{
			_compatibleKit = new GameObject("HuevitoCompatibleArena");
			Camera main = Camera.main;
			Vector3 val = (((Object)(object)main == (Object)null) ? Vector3.zero : ((Component)main).transform.position);
			float num = (((Object)(object)main == (Object)null) ? 4f : main.orthographicSize);
			val.z = 0f;
			float num2 = Mathf.Max(3.2f, num * 1.35f);
			if (_config.Has("moving_platforms"))
			{
				CreateAnchor("HuevitoPlatform_Compat", val + new Vector3(0f, (0f - num) * 0.58f, 0f), new Vector2(2.2f, 0.25f), new Color(0.25f, 0.9f, 1f, 1f), trigger: false);
			}
			if (_config.Has("destructible_objects"))
			{
				CreateAnchor("HuevitoBreakable_Compat", val + new Vector3(0f, num * 0.35f, 0f), new Vector2(0.7f, 0.7f), new Color(1f, 0.55f, 0.15f, 1f), trigger: false);
			}
			if (_config.Has("unstable_portals"))
			{
				CreateAnchor("HuevitoPortal_A_Compat", val + new Vector3(0f - num2, 0f, 0f), new Vector2(0.85f, 1.8f), new Color(0.85f, 0.2f, 1f, 0.65f), trigger: true);
				CreateAnchor("HuevitoPortal_B_Compat", val + new Vector3(num2, 0f, 0f), new Vector2(0.85f, 1.8f), new Color(0.15f, 0.9f, 1f, 0.65f), trigger: true);
			}
			ShowBanner("Kit de arena Huevito creado: sus objetos son propios y no modifican colliders externos.", 5f);
			if (_config.Has("moving_platforms"))
			{
				CachePlatforms();
			}
			if (_config.Has("destructible_objects"))
			{
				CacheBreakables();
			}
			if (_config.Has("unstable_portals"))
			{
				CachePortals();
			}
		}
	}

	private GameObject CreateAnchor(string name, Vector3 position, Vector2 size, Color color, bool trigger)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(_compatibleKit.transform);
		val.transform.position = position;
		BoxCollider2D val2 = val.AddComponent<BoxCollider2D>();
		val2.size = Vector2.one;
		((Collider2D)val2).isTrigger = trigger;
		SpriteRenderer val3 = val.AddComponent<SpriteRenderer>();
		val3.sprite = SolidSprite;
		val3.color = color;
		val.transform.localScale = new Vector3(size.x, size.y, 1f);
		if (name.IndexOf("HuevitoBreakable", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			val.AddComponent<BreakableAnchor>();
		}
		return val;
	}

	private void DestroyCompatibleAnchors()
	{
		if ((Object)(object)_compatibleKit != (Object)null)
		{
			Object.Destroy((Object)(object)_compatibleKit);
		}
		_compatibleKit = null;
		_platforms.Clear();
		_breakables.Clear();
		_portalsA.Clear();
		_portalsB.Clear();
		_platformOrigins.Clear();
		_breakableActive.Clear();
	}

	private void UpdateMovingPlatforms()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: 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_009d: Unknown result type (might be due to invalid IL or missing references)
		if (_config == null || !_config.Has("moving_platforms"))
		{
			return;
		}
		for (int i = 0; i < _platforms.Count; i++)
		{
			GameObject val = _platforms[i];
			if (!((Object)(object)val == (Object)null))
			{
				Vector3 val2 = _platformOrigins[val];
				float num = (float)i * 0.9f;
				val.transform.position = val2 + new Vector3(Mathf.Sin((Time.time - _roundStartedAt) * 1.4f + num) * 1.4f, Mathf.Cos((Time.time - _roundStartedAt) * 1.1f + num) * 0.45f, 0f);
			}
		}
	}

	private void CachePortals()
	{
		_portalsA.Clear();
		_portalsB.Clear();
		GameObject[] array = Object.FindObjectsOfType<GameObject>();
		foreach (GameObject val in array)
		{
			if (!((Object)(object)val == (Object)null) && val.activeInHierarchy)
			{
				if (((Object)val).name.IndexOf("HuevitoPortal_A", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					_portalsA.Add(val);
				}
				if (((Object)val).name.IndexOf("HuevitoPortal_B", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					_portalsB.Add(val);
				}
			}
		}
		if (_portalsA.Count == 0 || _portalsB.Count == 0)
		{
			ShowBanner("Portales inestables: faltan anclas HuevitoPortal_A/B en este mapa.", 5f);
		}
	}

	private void UpdatePortals()
	{
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		if (_config == null || !_config.Has("unstable_portals") || _portalsA.Count == 0 || _portalsB.Count == 0)
		{
			return;
		}
		List<Player> list = CurrentPlayers();
		for (int i = 0; i < list.Count; i++)
		{
			Player val = list[i];
			int playerID = val.playerID;
			if (!_portalCooldown.ContainsKey(playerID) || !(Time.time < _portalCooldown[playerID]))
			{
				GameObject val2 = PortalDestination(((Component)val).transform.position, _portalsA, _portalsB);
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = PortalDestination(((Component)val).transform.position, _portalsB, _portalsA);
				}
				if (!((Object)(object)val2 == (Object)null))
				{
					((Component)val).transform.position = val2.transform.position + Vector3.up * 0.6f;
					_portalCooldown[playerID] = Time.time + 1.2f;
				}
			}
		}
	}

	private GameObject PortalDestination(Vector3 position, List<GameObject> source, List<GameObject> destination)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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)
		for (int i = 0; i < source.Count; i++)
		{
			Collider2D component = source[i].GetComponent<Collider2D>();
			if ((Object)(object)component != (Object)null)
			{
				Bounds bounds = component.bounds;
				if (((Bounds)(ref bounds)).Contains(position))
				{
					return destination[i % destination.Count];
				}
			}
		}
		return null;
	}

	private void UpdateShrinkingArena()
	{
		if (_config != null && _config.Has("shrinking_arena") && !((Object)(object)Camera.main == (Object)null))
		{
			if (!_baseCameraCaptured)
			{
				_baseCameraSize = Camera.main.orthographicSize;
				_baseCameraCaptured = true;
			}
			float num = Mathf.Clamp01((Time.time - _roundStartedAt) / 32f);
			Camera.main.orthographicSize = Mathf.Lerp(_baseCameraSize, Mathf.Max(2.6f, _baseCameraSize * 0.62f), num);
		}
	}

	private void ApplyBreakable(int index)
	{
		if (_breakables.Count == 0)
		{
			CacheBreakables();
		}
		if (index >= 0 && index < _breakables.Count)
		{
			_breakables[index].SetActive(false);
		}
	}

	private void CacheBreakables()
	{
		_breakables.Clear();
		GameObject[] array = Object.FindObjectsOfType<GameObject>();
		foreach (GameObject val in array)
		{
			if ((Object)(object)val != (Object)null && val.activeInHierarchy && ((Object)val).name.IndexOf("HuevitoBreakable", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				_breakables.Add(val);
				if (!_breakableActive.ContainsKey(val))
				{
					_breakableActive[val] = true;
				}
			}
		}
		if (_breakables.Count == 0)
		{
			ShowBanner("Objetos destructibles: este mapa no tiene anclas HuevitoBreakable.", 5f);
		}
	}

	private int ChooseBreakableIndex(Random random)
	{
		if (_config == null || !_config.Has("destructible_objects"))
		{
			return -1;
		}
		CacheBreakables();
		if (_breakables.Count != 0)
		{
			return random.Next(_breakables.Count);
		}
		return -1;
	}

	private void RestoreMapObjects()
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		foreach (KeyValuePair<GameObject, Vector3> platformOrigin in _platformOrigins)
		{
			if ((Object)(object)platformOrigin.Key != (Object)null)
			{
				platformOrigin.Key.transform.position = platformOrigin.Value;
			}
		}
		foreach (KeyValuePair<GameObject, bool> item in _breakableActive)
		{
			if ((Object)(object)item.Key != (Object)null)
			{
				item.Key.SetActive(item.Value);
			}
		}
		_platforms.Clear();
		_portalsA.Clear();
		_portalsB.Clear();
	}

	private void RecordWinner()
	{
		if (_roundState.RoundNumber != _lastRecordedRound)
		{
			Player val = FindLikelyWinner();
			if (!((Object)(object)val == (Object)null))
			{
				_lastRecordedRound = _roundState.RoundNumber;
				int playerID = val.playerID;
				_wins[playerID] = ((!_wins.ContainsKey(playerID)) ? 1 : (_wins[playerID] + 1));
				ShowBanner("Punto para jugador " + (playerID + 1) + ". Lleva " + _wins[playerID] + " victoria(s).", 4f);
			}
		}
	}

	private Player FindLikelyWinner()
	{
		List<Player> list = CurrentPlayers();
		Player result = null;
		int num = 0;
		for (int i = 0; i < list.Count; i++)
		{
			if (!IsDead(list[i]))
			{
				result = list[i];
				num++;
			}
		}
		if (num != 1)
		{
			return null;
		}
		return result;
	}

	private int FindChampion()
	{
		int result = -1;
		int num = -1;
		foreach (KeyValuePair<int, int> win in _wins)
		{
			if (win.Value > num)
			{
				result = win.Key;
				num = win.Value;
			}
		}
		return result;
	}

	private string EncodeWins()
	{
		List<string> list = new List<string>();
		foreach (KeyValuePair<int, int> win in _wins)
		{
			list.Add(win.Key + ":" + win.Value);
		}
		return string.Join("|", list.ToArray());
	}

	private void DecodeWins(string encoded)
	{
		_wins.Clear();
		if (string.IsNullOrEmpty(encoded))
		{
			return;
		}
		string[] array = encoded.Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			string[] array2 = array[i].Split(new char[1] { ':' });
			if (array2.Length == 2 && int.TryParse(array2[0], out var result) && int.TryParse(array2[1], out var result2))
			{
				_wins[result] = result2;
			}
		}
	}

	private string BuildAward()
	{
		int num = FindChampion();
		if (num < 0)
		{
			return "Premio absurdo: todos ganaron moralmente.";
		}
		string[] array = new string[4] { "Premio al rey de la yema", "Medalla al campeon sospechoso", "Trofeo al ultimo que miro la pantalla", "Copa de oro imaginaria" };
		int num2 = Math.Abs((_config.Seed + _roundState.RoundNumber * 17) % array.Length);
		return array[num2] + ": jugador " + (num + 1) + ".";
	}

	private void PatchExternalCompatibility()
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		try
		{
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				if (!(type == null))
				{
					break;
				}
				type = assemblies[i].GetType("CardsPlusPlugin.Cards.Cyberpunk.CyberCardEffect", throwOnError: false);
			}
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "SetFont", (Type[])null, (Type[])null));
			if (!(methodInfo == null))
			{
				MethodInfo method = typeof(ChaosDirector).GetMethod("SkipCardsPlusBrokenFont", BindingFlags.Static | BindingFlags.NonPublic);
				new Harmony("com.mauricio.rounds.huevito-rey.compat").Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				_cardsPlusPatched = true;
				if (_log != null)
				{
					_log.LogInfo((object)"Compatibilidad: se evita el SetFont incompatible de CardsPlus Cyberpunk; se conserva la carta con su fuente por defecto.");
				}
			}
		}
		catch (Exception ex)
		{
			if (_log != null)
			{
				_log.LogWarning((object)("Compatibilidad CardsPlus no aplicada: " + ex.Message));
			}
		}
	}

	private static bool SkipCardsPlusBrokenFont()
	{
		return false;
	}

	private string DescribeRound()
	{
		string text = string.Empty;
		if (_roundState.EventId != "none")
		{
			text = text + _roundState.EventId + " ";
		}
		if (_roundState.RuleId != "none")
		{
			text = text + _roundState.RuleId + " ";
		}
		if (_roundState.Champion >= 0)
		{
			object obj = text;
			text = string.Concat(obj, "campeon ", _roundState.Champion + 1, " ");
		}
		if (_roundState.RivalA >= 0)
		{
			object obj2 = text;
			text = string.Concat(obj2, "rivalidad ", _roundState.RivalA + 1, " vs ", _roundState.RivalB + 1, " ");
		}
		if (_roundState.PunishmentTarget >= 0)
		{
			text = text + "castigo para " + (_roundState.PunishmentTarget + 1);
		}
		if (!string.IsNullOrEmpty(text))
		{
			return text.Trim();
		}
		return "sin modificador especial";
	}

	private List<Player> CurrentPlayers()
	{
		List<Player> list = new List<Player>();
		if ((Object)(object)PlayerManager.instance == (Object)null || PlayerManager.instance.players == null)
		{
			return list;
		}
		for (int i = 0; i < PlayerManager.instance.players.Count; i++)
		{
			if ((Object)(object)PlayerManager.instance.players[i] != (Object)null)
			{
				list.Add(PlayerManager.instance.players[i]);
			}
		}
		return list;
	}

	private Player FindPlayer(int id)
	{
		List<Player> list = CurrentPlayers();
		for (int i = 0; i < list.Count; i++)
		{
			if (list[i].playerID == id)
			{
				return list[i];
			}
		}
		return null;
	}

	private bool IsDead(Player player)
	{
		if (TryMember(player, "dead", out var value) && value is bool)
		{
			return (bool)value;
		}
		if ((Object)(object)player.data != (Object)null && TryMember(player.data, "dead", out value) && value is bool)
		{
			return (bool)value;
		}
		if ((Object)(object)player.data != (Object)null && TryMember(player.data, "health", out value) && value != null)
		{
			if (TryMember(value, "dead", out value) && value is bool)
			{
				return (bool)value;
			}
			if (TryMember(value, "isDead", out value) && value is bool)
			{
				return (bool)value;
			}
		}
		return false;
	}

	private static bool TryMember(object target, string name, out object value)
	{
		value = null;
		if (target == null)
		{
			return false;
		}
		Type type = target.GetType();
		FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			value = field.GetValue(target);
			return true;
		}
		PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (property != null && property.GetIndexParameters().Length == 0)
		{
			value = property.GetValue(target, null);
			return true;
		}
		return false;
	}

	private void ShowBanner(string text, float seconds)
	{
		_banner = text;
		_bannerUntil = Time.time + seconds;
		if (_log != null)
		{
			_log.LogInfo((object)text);
		}
	}

	private static int Clamp(int value, int min, int max)
	{
		if (value >= min)
		{
			if (value <= max)
			{
				return value;
			}
			return max;
		}
		return min;
	}
}
internal static class EggArt
{
	private static Sprite _eggSprite;

	private static GameObject _cardArt;

	private static Sprite EggSprite
	{
		get
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0076: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_eggSprite != (Object)null)
			{
				return _eggSprite;
			}
			string path = Path.Combine(Paths.PluginPath, "HuevitoRey", "huevito-rey.png");
			if (File.Exists(path))
			{
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(path)))
				{
					((Object)val).name = "HuevitoRey_AttachedImage";
					((Texture)val).filterMode = (FilterMode)1;
					_eggSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 256f);
					((Object)_eggSprite).name = "HuevitoRey_AttachedSprite";
					return _eggSprite;
				}
				Object.Destroy((Object)(object)val);
			}
			Texture2D val2 = new Texture2D(32, 40, (TextureFormat)4, false);
			((Object)val2).name = "HuevitoRey_EggTexture";
			((Texture)val2).filterMode = (FilterMode)0;
			((Texture)val2).wrapMode = (TextureWrapMode)1;
			Texture2D val3 = val2;
			Color32[] array = (Color32[])(object)new Color32[1280];
			for (int i = 0; i < array.Length; i++)
			{
				ref Color32 reference = ref array[i];
				reference = new Color32((byte)0, (byte)0, (byte)0, (byte)0);
			}
			for (int j = 2; j < 38; j++)
			{
				float num = ((float)j - 2f) / 36f;
				float num2 = Mathf.Lerp(10f, 14f, num);
				float num3 = 16f + Mathf.Sin(num * (float)Math.PI) * 1.5f;
				float num4 = 20f;
				for (int k = 0; k < 32; k++)
				{
					float num5 = Vector2.Distance(new Vector2((float)k, (float)j), new Vector2(num3, num4));
					if (num5 <= num2)
					{
						byte b = (byte)Mathf.Clamp(246f - num * 20f, 210f, 246f);
						ref Color32 reference2 = ref array[j * 32 + k];
						reference2 = new Color32(b, b, (byte)220, byte.MaxValue);
					}
				}
			}
			for (int l = 14; l <= 23; l++)
			{
				for (int m = 11; m <= 20; m++)
				{
					if (Vector2.Distance(new Vector2((float)m, (float)l), new Vector2(15.5f, 18.5f)) <= 5f)
					{
						ref Color32 reference3 = ref array[l * 32 + m];
						reference3 = new Color32(byte.MaxValue, (byte)177, (byte)22, byte.MaxValue);
					}
				}
			}
			ref Color32 reference4 = ref array[428];
			reference4 = new Color32((byte)35, (byte)25, (byte)25, byte.MaxValue);
			ref Color32 reference5 = ref array[435];
			reference5 = new Color32((byte)35, (byte)25, (byte)25, byte.MaxValue);
			ref Color32 reference6 = ref array[334];
			reference6 = new Color32((byte)35, (byte)25, (byte)25, byte.MaxValue);
			ref Color32 reference7 = ref array[337];
			reference7 = new Color32((byte)35, (byte)25, (byte)25, byte.MaxValue);
			val3.SetPixels32(array);
			val3.Apply();
			_eggSprite = Sprite.Create(val3, new Rect(0f, 0f, 32f, 40f), new Vector2(0.5f, 0.5f), 32f);
			((Object)_eggSprite).name = "HuevitoRey_EggSprite";
			return _eggSprite;
		}
	}

	public static GameObject CreateCardArt()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_cardArt != (Object)null)
		{
			return _cardArt;
		}
		GameObject val = new GameObject("HuevitoReyCardArt");
		val.AddComponent<SpriteRenderer>().sprite = EggSprite;
		val.transform.localScale = new Vector3(1.35f, 1.35f, 1f);
		val.SetActive(false);
		Object.DontDestroyOnLoad((Object)(object)val);
		_cardArt = val;
		return _cardArt;
	}

	public static void PaintProjectileAsEgg(GameObject projectile)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		SpriteRenderer[] componentsInChildren = projectile.GetComponentsInChildren<SpriteRenderer>(true);
		SpriteRenderer[] array = componentsInChildren;
		foreach (SpriteRenderer val in array)
		{
			val.sprite = EggSprite;
			val.color = Color.white;
		}
		Transform transform = projectile.transform;
		transform.localScale *= 1.35f * ChaosDirector.ProjectileScaleMultiplier;
	}

	public static void SpawnYolkBurst(Vector3 position)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("HuevitoRey_Yema");
		val.transform.position = position;
		ParticleSystem val2 = val.AddComponent<ParticleSystem>();
		MainModule main = val2.main;
		((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(1f, 0.72f, 0.05f, 1f));
		((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.65f);
		((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(4f);
		((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.16f);
		EmissionModule emission = val2.emission;
		((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f);
		val2.Emit(18);
		Object.Destroy((Object)(object)val, 1.1f);
	}
}
public sealed class HuevitoReyCard : CustomEffectCard<HuevitoReyEffect>
{
	public override CardDetails<HuevitoReyEffect> Details
	{
		get
		{
			CardDetails<HuevitoReyEffect> val = new CardDetails<HuevitoReyEffect>();
			val.Title = "Huevito rey";
			val.Description = "Tus disparos son huevos enormes. Si te pega, te manda al lobby de la gallina. Explota en yema!";
			val.ModName = "Huevito Rey";
			val.Rarity = (Rarity)2;
			val.Theme = (CardThemeColorType)1;
			val.Art = EggArt.CreateCardArt();
			return val;
		}
	}

	public override void SetupCard(CardInfo cardInfo, Gun gun, ApplyCardStats cardStats, CharacterStatModifiers statModifiers, Block block)
	{
		gun.damage = 999f;
		gun.knockback = 3f;
		gun.projectileSpeed = 0.85f;
		cardInfo.allowMultiple = false;
	}
}
public sealed class HuevitoReyEffect : CardEffect
{
	public override void OnShoot(GameObject projectile)
	{
		if (!((Object)(object)projectile == (Object)null))
		{
			EggArt.PaintProjectileAsEgg(projectile);
			Rigidbody2D component = projectile.GetComponent<Rigidbody2D>();
			if ((Object)(object)component != (Object)null)
			{
				component.angularVelocity = Random.Range(-720f, 720f);
			}
		}
	}

	public override void OnBulletHit(GameObject projectile, HitInfo hit)
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)projectile != (Object)null)
		{
			EggArt.SpawnYolkBurst(projectile.transform.position);
		}
	}
}
internal sealed class MatchConfig
{
	public const int Protocol = 1;

	public int Seed;

	public int Intensity = 1;

	public int MaxActive = 4;

	public bool VoteMode;

	public string[] Active = new string[0];

	public bool Has(string id)
	{
		return ModifierCatalog.Contains(Active, id);
	}

	public string EncodeActive()
	{
		if (Active != null)
		{
			return string.Join("|", Active);
		}
		return string.Empty;
	}

	public static MatchConfig FromNetwork(object[] data, int startIndex)
	{
		MatchConfig matchConfig = new MatchConfig();
		if (data == null || data.Length <= startIndex + 4)
		{
			return matchConfig;
		}
		matchConfig.Seed = Convert.ToInt32(data[startIndex]);
		string text = Convert.ToString(data[startIndex + 1]);
		matchConfig.Active = (string.IsNullOrEmpty(text) ? new string[0] : text.Split(new char[1] { '|' }, StringSplitOptions.RemoveEmptyEntries));
		matchConfig.Intensity = Clamp(Convert.ToInt32(data[startIndex + 2]), 1, 3);
		matchConfig.MaxActive = Clamp(Convert.ToInt32(data[startIndex + 3]), 1, ModifierCatalog.All.Length);
		matchConfig.VoteMode = Convert.ToBoolean(data[startIndex + 4]);
		return matchConfig;
	}

	private static int Clamp(int value, int min, int max)
	{
		if (value >= min)
		{
			if (value <= max)
			{
				return value;
			}
			return max;
		}
		return min;
	}
}
internal static class ModifierCatalog
{
	public const string RandomEvents = "random_events";

	public const string PunishmentRoulette = "punishment_roulette";

	public const string ChampionTarget = "champion_target";

	public const string Rivalries = "rivalries";

	public const string RuleVote = "rule_vote";

	public const string MovingPlatforms = "moving_platforms";

	public const string DestructibleObjects = "destructible_objects";

	public const string UnstablePortals = "unstable_portals";

	public const string ShrinkingArena = "shrinking_arena";

	public const string AbsurdAwards = "absurd_awards";

	public static readonly string[] All = new string[10] { "random_events", "punishment_roulette", "champion_target", "rivalries", "rule_vote", "moving_platforms", "destructible_objects", "unstable_portals", "shrinking_arena", "absurd_awards" };

	public static string Label(string id)
	{
		return id switch
		{
			"random_events" => "Eventos aleatorios", 
			"punishment_roulette" => "Ruleta de castigos", 
			"champion_target" => "Cazar al campeon", 
			"rivalries" => "Rivalidades", 
			"rule_vote" => "Regla del round", 
			"moving_platforms" => "Plataformas moviles", 
			"destructible_objects" => "Objetos destructibles", 
			"unstable_portals" => "Portales inestables", 
			"shrinking_arena" => "Arena menguante", 
			"absurd_awards" => "Premios absurdos", 
			_ => id, 
		};
	}

	public static bool Contains(string[] values, string id)
	{
		if (values == null)
		{
			return false;
		}
		for (int i = 0; i < values.Length; i++)
		{
			if (string.Equals(values[i], id, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
		}
		return false;
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("com.mauricio.rounds.huevito-rey", "Huevito Rey", "1.6.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInProcess("Rounds.exe")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string ModId = "com.mauricio.rounds.huevito-rey";

	public const string ModName = "Huevito Rey";

	public const string Version = "1.6.0";

	private void Start()
	{
		CustomCard.BuildCard<HuevitoReyCard>();
		ChaosDirector.Create(((BaseUnityPlugin)this).Logger, (BaseUnityPlugin)(object)this);
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Huevito Rey cargado: la yema manda y el anfitrion puede abrir las reglas con F8 o con el boton visible.");
	}
}
internal sealed class RoundState
{
	public int RoundNumber;

	public string EventId = "none";

	public string RuleId = "none";

	public int PunishmentTarget = -1;

	public int RivalA = -1;

	public int RivalB = -1;

	public int Champion = -1;

	public int BreakableIndex = -1;

	public bool Ready;
}