Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RepoAmigos v1.5.0
RepoAmigos.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using RepoAmigos.Patches; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RepoAmigos")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.5.0.0")] [assembly: AssemblyInformationalVersion("1.5.0+e3104b6eec231ad272c5f572b8d3df08ee8dbf9b")] [assembly: AssemblyProduct("RepoAmigos")] [assembly: AssemblyTitle("RepoAmigos")] [assembly: AssemblyVersion("1.5.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 RepoAmigos { [BepInPlugin("com.usuario.repoamigos", "RepoAmigos", "1.5.0")] [BepInProcess("REPO.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.usuario.repoamigos"; public const string PluginName = "RepoAmigos"; public const string PluginVersion = "1.5.0"; private Harmony _harmony; internal static ConfigEntry<bool> VerboseLogging; internal static ManualLogSource Log { get; private set; } internal static Plugin Instance { get; private set; } private void Awake() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_016c: 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_022e: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; BindConfig(); ExtractionOnDemand.BindConfig(((BaseUnityPlugin)this).Config); ReviveEnExtractor.BindConfig(((BaseUnityPlugin)this).Config); GeneradorDePruebas.BindConfig(((BaseUnityPlugin)this).Config); CarritoEncoge.BindConfig(((BaseUnityPlugin)this).Config); ComprobacionDeVersion.BindConfig(((BaseUnityPlugin)this).Config); Roles.BindConfig(((BaseUnityPlugin)this).Config); RolMedico.BindConfig(((BaseUnityPlugin)this).Config); RolIngeniero.BindConfig(((BaseUnityPlugin)this).Config); RolSaboteador.BindConfig(((BaseUnityPlugin)this).Config); RolRastreador.BindConfig(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.usuario.repoamigos"); _harmony.PatchAll(Assembly.GetExecutingAssembly()); Log.LogInfo((object)("RepoAmigos v1.5.0 cargado. " + $"Metodos parcheados: {_harmony.GetPatchedMethods().Count()}")); Log.LogInfo((object)("Extraccion manual: " + (ExtractionOnDemand.Enabled.Value ? "ACTIVADA" : "desactivada"))); Log.LogInfo((object)("Revivir en extractor: " + (ReviveEnExtractor.Enabled.Value ? $"ACTIVADO ({ReviveEnExtractor.Segundos.Value}s)" : "desactivado"))); Log.LogInfo((object)($"Pruebas: Activado={GeneradorDePruebas.Enabled.Value}, " + $"Tecla={GeneradorDePruebas.Tecla.Value}, " + $"Cantidad={GeneradorDePruebas.Cantidad.Value}")); Log.LogInfo((object)(Roles.Enabled.Value ? ($"Roles: ACTIVADOS (minimo {Roles.MinJugadores.Value} jugadores) " + $"medico[{RolMedico.Tecla.Value}]={RolMedico.Enabled.Value} " + $"ingeniero={RolIngeniero.Enabled.Value} " + $"saboteador[{RolSaboteador.Tecla.Value}]={RolSaboteador.Enabled.Value} " + $"rastreador={RolRastreador.Enabled.Value}") : "Roles: desactivados")); } private void Update() { GeneradorDePruebas.Tick("Plugin"); } private void OnDestroy() { Log.LogWarning((object)"OnDestroy: el componente del plugin se ha destruido. Los parches Harmony se mantienen a proposito."); ExtractionOnDemand.DesconectarRed(); Roles.DesconectarRed(); } private void BindConfig() { VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LogDetallado", false, "Escribe informacion extra en la consola de BepInEx. Util para depurar, ruidoso para jugar."); } internal static void Debug(string mensaje) { if (VerboseLogging != null && VerboseLogging.Value) { Log.LogInfo((object)("[debug] " + mensaje)); } } } } namespace RepoAmigos.Patches { internal static class CarritoEncoge { private sealed class Encogido { public Vector3 TamanoOriginal; public float VistoPorUltimaVez; } [HarmonyPatch(typeof(PhysGrabCart), "ObjectsInCart")] private static class ReconciliarContenido { private static void Prefix(out float __state, float ___objectInCartCheckTimer) { __state = ___objectInCartCheckTimer; } private static void Postfix(float __state, float ___objectInCartCheckTimer, List<PhysGrabObject> ___itemsInCart) { if (Enabled == null || !Enabled.Value || ___objectInCartCheckTimer <= __state) { return; } if (___itemsInCart != null) { foreach (PhysGrabObject item in ___itemsInCart) { Marcar(item); } } DevolverALosQueSalieron(); } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] private static class SoltarTodoAlCambiarDeNivel { private static void Prefix() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (_dentro.Count == 0) { return; } int num = 0; foreach (KeyValuePair<PhysGrabObject, Encogido> item in _dentro) { if (!((Object)(object)item.Key == (Object)null)) { ((Component)item.Key).transform.localScale = item.Value.TamanoOriginal; num++; } } Plugin.Debug($"Carrito: cambio de nivel, {num} objetos devueltos a su tamano."); _dentro.Clear(); } } internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> Escala; internal static ConfigEntry<bool> SoloValiosos; private static readonly Dictionary<PhysGrabObject, Encogido> _dentro = new Dictionary<PhysGrabObject, Encogido>(); private const float MargenSalida = 1.6f; private static readonly FieldInfo _campoValioso = AccessTools.Field(typeof(PhysGrabObject), "isValuable"); private static readonly FieldInfo _campoEnemigo = AccessTools.Field(typeof(PhysGrabObject), "isEnemy"); private static readonly FieldInfo _campoJugador = AccessTools.Field(typeof(PhysGrabObject), "isPlayer"); internal static void BindConfig(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown Enabled = config.Bind<bool>("Carrito", "Activado", true, "Encoge los objetos mientras estan dentro del C.A.R.T. y les devuelve su tamano al sacarlos."); Escala = config.Bind<float>("Carrito", "EscalaDentro", 0.75f, new ConfigDescription("Tamano dentro del carrito respecto al original. 0.75 los deja al 75%; 0.25 seria encogerlos un 75%.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>())); SoloValiosos = config.Bind<bool>("Carrito", "SoloValiosos", true, "true: solo se encoge el botin, que es lo que de verdad ocupa sitio. false: tambien objetos normales. Aun en false hay cosas que NUNCA se tocan (armas equipables, jugadores, enemigos, puertas y bisagras), porque encogerlas rompia el nivel o el propio objeto."); } private static bool LaBanderaDice(FieldInfo campo, PhysGrabObject objeto, bool siNoSePuede) { if (campo == null) { return siNoSePuede; } object value = campo.GetValue(objeto); if (!(value is bool)) { return siNoSePuede; } return (bool)value; } private static bool SePuedeEncoger(PhysGrabObject objeto) { if ((Object)(object)objeto == (Object)null) { return false; } if ((Object)(object)((Component)objeto).GetComponent<PhysGrabCart>() != (Object)null) { return false; } if (LaBanderaDice(_campoEnemigo, objeto, siNoSePuede: true)) { return false; } if (LaBanderaDice(_campoJugador, objeto, siNoSePuede: true)) { return false; } if ((Object)(object)((Component)objeto).GetComponentInChildren<ItemEquippable>(true) != (Object)null) { return false; } if ((Object)(object)((Component)objeto).GetComponentInChildren<PlayerDeathHead>(true) != (Object)null) { return false; } if ((Object)(object)((Component)objeto).GetComponentInChildren<PhysGrabHinge>(true) != (Object)null) { return false; } if (SoloValiosos.Value && !LaBanderaDice(_campoValioso, objeto, siNoSePuede: false)) { return false; } return true; } private static void Marcar(PhysGrabObject objeto) { //IL_0034: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_007c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)objeto == (Object)null) { return; } if (_dentro.TryGetValue(objeto, out var value)) { value.VistoPorUltimaVez = Time.time; } else if (SePuedeEncoger(objeto)) { Vector3 localScale = ((Component)objeto).transform.localScale; if (!(((Vector3)(ref localScale)).sqrMagnitude < 0.01f)) { _dentro[objeto] = new Encogido { TamanoOriginal = localScale, VistoPorUltimaVez = Time.time }; ((Component)objeto).transform.localScale = localScale * Escala.Value; Plugin.Debug($"Carrito: '{((Object)objeto).name}' encogido al {Escala.Value:P0}."); } } } private static void DevolverALosQueSalieron() { //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (_dentro.Count == 0) { return; } List<PhysGrabObject> list = null; foreach (KeyValuePair<PhysGrabObject, Encogido> item in _dentro) { if ((Object)(object)item.Key == (Object)null) { (list ?? (list = new List<PhysGrabObject>())).Add(item.Key); } else if (!(Time.time - item.Value.VistoPorUltimaVez < 1.6f)) { ((Component)item.Key).transform.localScale = item.Value.TamanoOriginal; (list ?? (list = new List<PhysGrabObject>())).Add(item.Key); Plugin.Debug("Carrito: '" + ((Object)item.Key).name + "' recupera su tamano."); } } if (list == null) { return; } foreach (PhysGrabObject item2 in list) { _dentro.Remove(item2); } } } internal static class ComprobacionDeVersion { internal static ConfigEntry<bool> Enabled; private static readonly Dictionary<string, string> _versiones = new Dictionary<string, string>(); private static readonly Dictionary<string, float> _vistoDesde = new Dictionary<string, float>(); private static float _proximoAnuncio; private static float _proximaRevision; private static string _ultimoProblema = ""; private const float MargenDeGracia = 25f; private const float CadaCuantoAnuncio = 15f; private const float CadaCuantoRevision = 5f; private static readonly FieldInfo _campoNombre = AccessTools.Field(typeof(PlayerAvatar), "playerName"); internal static void BindConfig(ConfigFile config) { Enabled = config.Bind<bool>("Version", "AvisarDesajuste", true, "Avisa en pantalla si algun jugador de la sala lleva otra version del mod o no lo lleva. Muy recomendable dejarlo activado: un desajuste de version no da ningun error, simplemente hace que los roles no funcionen."); } internal static void AlCambiarNivel() { _versiones.Clear(); _vistoDesde.Clear(); _proximoAnuncio = 2f; _proximaRevision = 25f; _ultimoProblema = ""; } internal static void Tick() { if (Enabled != null && Enabled.Value && Roles.EnPartida()) { _proximoAnuncio -= Time.deltaTime; if (_proximoAnuncio <= 0f) { _proximoAnuncio = 15f; Anunciar(); } _proximaRevision -= Time.deltaTime; if (_proximaRevision <= 0f) { _proximaRevision = 5f; Revisar(); } } } private static void Anunciar() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_006d: Expected O, but got Unknown PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return; } string text = SemiFunc.PlayerGetSteamID(instance); if (!string.IsNullOrEmpty(text)) { _versiones[text] = "1.5.0"; if (SemiFunc.IsMultiplayer() && PhotonNetwork.NetworkingClient != null && PhotonNetwork.InRoom) { PhotonNetwork.RaiseEvent((byte)178, (object)(text + "|1.5.0"), new RaiseEventOptions { Receivers = (ReceiverGroup)0 }, SendOptions.SendReliable); } } } internal static void Recibir(object datos) { if (datos is string text) { int num = text.IndexOf('|'); if (num > 0 && num != text.Length - 1) { _versiones[text.Substring(0, num)] = text.Substring(num + 1); } } } private static string Nombre(PlayerAvatar avatar) { if (_campoNombre == null) { return "Alguien"; } string text = _campoNombre.GetValue(avatar) as string; if (!string.IsNullOrEmpty(text)) { return text; } return "Alguien"; } private static void Revisar() { if (!SemiFunc.IsMultiplayer()) { return; } List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count <= 1) { return; } List<string> list2 = new List<string>(); List<string> list3 = new List<string>(); foreach (PlayerAvatar item in list) { if ((Object)(object)item == (Object)null) { continue; } string text = SemiFunc.PlayerGetSteamID(item); if (string.IsNullOrEmpty(text)) { continue; } if (!_vistoDesde.ContainsKey(text)) { _vistoDesde[text] = Time.time; } if (_versiones.TryGetValue(text, out var value)) { if (value != "1.5.0") { list2.Add(Nombre(item) + " lleva la " + value); } } else if (Time.time - _vistoDesde[text] >= 25f) { list3.Add(Nombre(item)); } } if (list2.Count == 0 && list3.Count == 0) { _ultimoProblema = ""; return; } string text2 = string.Join(",", list2.ToArray()) + "//" + string.Join(",", list3.ToArray()); if (!(text2 == _ultimoProblema)) { _ultimoProblema = text2; Avisar(list2, list3); } } private static void Avisar(List<string> distintos, List<string> ausentes) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) SemiFunc.UIBigMessage("MOD DESINCRONIZADO", "!", 35f, new Color(1f, 0.4f, 0.2f), Color.white); string text = ((distintos.Count > 0 && ausentes.Count > 0) ? (string.Join(", ", distintos.ToArray()) + " - sin el mod: " + string.Join(", ", ausentes.ToArray())) : ((distintos.Count <= 0) ? ("Sin el mod (o version anterior a la 1.3.0): " + string.Join(", ", ausentes.ToArray())) : (string.Join(", ", distintos.ToArray()) + " - tu la 1.5.0"))); SemiFunc.UIFocusText(text, new Color(1f, 0.4f, 0.2f), Color.white, 8f); Plugin.Log.LogWarning((object)("DESAJUSTE DE VERSION. Yo llevo la 1.5.0. " + text + ". Los roles no van a funcionar bien hasta que todos tengan la misma DLL. Recordad que arrancar desde Steam corre el juego en vanilla sin avisar.")); } } internal static class ExtractionOnDemand { private sealed class Estado { public bool Esperando; public bool Armado; public bool AvisoMostrado; public float LuzIntensidad = -1f; public Color LuzColor; public Transform Estacion; public bool YaCompletado; public PhysGrabObject Pato; public Vector3 PatoPosicion; public Quaternion PatoRotacion; public bool Activo; public bool MetaConocida; public int FaltaBotin; } [HarmonyPatch(typeof(ExtractionPoint), "Start")] private static class ConservarBotonDeTienda { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instrucciones) { MethodInfo destroy = AccessTools.Method(typeof(Object), "Destroy", new Type[1] { typeof(Object) }, (Type[])null); MethodInfo reemplazo = AccessTools.Method(typeof(ExtractionOnDemand), "DestruirSalvoQueLoConservemos", (Type[])null, (Type[])null); foreach (CodeInstruction instruccione in instrucciones) { if (destroy != null && CodeInstructionExtensions.Calls(instruccione, destroy)) { yield return new CodeInstruction(OpCodes.Call, (object)reemplazo); } else { yield return instruccione; } } } private static void Postfix(ExtractionPoint __instance, bool ___isShop) { if (Enabled.Value && BotonGrande.Value && !___isShop) { Transform shopStation = __instance.shopStation; if (!((Object)(object)shopStation == (Object)null)) { EstadoDe(__instance).Estacion = shopStation; __instance.shopStation = null; ((Component)shopStation).gameObject.SetActive(true); DesplegarEstacion(shopStation, __instance); } } } } private sealed class Vinculo { public ExtractionPoint Punto; } [HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")] private static class PatoNoSeLevanta { private static bool Prefix(PhysGrabObject __instance) { if (!Enabled.Value || !UsarPato.Value) { return true; } if (!_patos.TryGetValue(__instance, out var value)) { return true; } if ((Object)(object)value.Punto != (Object)null) { if (EstadoDe(value.Punto).Esperando) { object? obj = _photonViewExtractor?.GetValue(value.Punto); PhotonView view = (PhotonView)((obj is PhotonView) ? obj : null); Plugin.Debug("Pato pulsado: lanzando la extraccion."); Solicitar(value.Punto, view); } else { AvisarPorQueNoSePuede(EstadoDe(value.Punto)); } } return false; } } [HarmonyPatch(typeof(ItemEquippable), "Update")] private static class SilenciarEquipableDelPato { private static bool Prefix(ItemEquippable __instance) { if (!Enabled.Value || _equipablesDelPato.Count == 0) { return true; } return !_equipablesDelPato.Contains(__instance); } } [HarmonyPatch(typeof(ItemRubberDuck), "Start")] private static class DesnudarPatoEnCadaCliente { private static void Postfix(ItemRubberDuck __instance) { PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); object[] array = (((Object)(object)component != (Object)null) ? component.InstantiationData : null); if (array != null && array.Length != 0 && array[0] is string text && !(text != "RepoAmigos:BotonPato")) { DesnudarPato(((Component)__instance).gameObject); } } } [HarmonyPatch(typeof(ExtractionPoint), "StateSetRPC")] private static class SonidoAlPulsar { private static void Prefix(ExtractionPoint __instance, State state, bool ___isShop) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (!Enabled.Value || ___isShop || (int)state != 3) { return; } try { Estado estado = EstadoDe(__instance); Vector3 val = (((Object)(object)estado.Pato != (Object)null) ? ((Component)estado.Pato).transform.position : ((Component)__instance).transform.position); if (__instance.soundButton != null) { __instance.soundButton.Play(val, 1f, 1f, 1f, 1f); } } catch { } } } [HarmonyPatch(typeof(ExtractionPoint), "StateSet")] private static class BloquearSuccessAutomatico { private static bool Prefix(ExtractionPoint __instance, State newState, bool ___isShop) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if (!Enabled.Value) { return true; } if ((int)newState != 3) { return true; } if (___isShop) { return true; } Estado estado = EstadoDe(__instance); if (estado.Armado) { estado.Armado = false; estado.Esperando = false; estado.AvisoMostrado = false; Plugin.Debug("Extraccion autorizada por pulsacion del boton."); return true; } return false; } } [HarmonyPatch(typeof(ExtractionPoint), "Update")] private static class MantenerBotonUsable { private static void Postfix(ExtractionPoint __instance, bool ___isShop, bool ___haulGoalFetched, int ___haulCurrent, State ___currentState) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Invalid comparison between Unknown and I4 //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) if (!Enabled.Value) { return; } AsegurarRed(); Estado estado = EstadoDe(__instance); bool flag = ___haulGoalFetched && __instance.haulGoal - ___haulCurrent <= 0; bool flag2 = (estado.Esperando = !___isShop && (int)___currentState == 2 && flag); estado.Activo = (int)___currentState == 2; estado.MetaConocida = ___haulGoalFetched; estado.FaltaBotin = __instance.haulGoal - ___haulCurrent; if ((int)___currentState == 7 && !estado.YaCompletado) { estado.YaCompletado = true; if ((Object)(object)estado.Estacion != (Object)null) { ((Component)estado.Estacion).gameObject.SetActive(false); } RetirarPato(estado); Plugin.Debug("Extraccion completada: boton/pato retirado."); } if ((Object)(object)estado.Pato != (Object)null && SemiFunc.IsMasterClientOrSingleplayer()) { Transform transform = ((Component)estado.Pato).transform; Vector3 val = transform.position - estado.PatoPosicion; if (((Vector3)(ref val)).sqrMagnitude > 0.0004f) { transform.position = estado.PatoPosicion; transform.rotation = estado.PatoRotacion; } Rigidbody component = ((Component)estado.Pato).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null && !component.isKinematic) { component.velocity = Vector3.zero; component.angularVelocity = Vector3.zero; component.isKinematic = true; } } if (flag2 && (Object)(object)estado.Pato != (Object)null && SemiFunc.IsMasterClientOrSingleplayer()) { List<PhysGrabber> playerGrabbing = estado.Pato.playerGrabbing; if (playerGrabbing != null && playerGrabbing.Count > 0) { Plugin.Debug("Pato agarrado: lanzando la extraccion."); Ejecutar(__instance); } } if (!flag2) { if (estado.LuzIntensidad >= 0f && (Object)(object)__instance.buttonLight != (Object)null) { __instance.buttonLight.intensity = estado.LuzIntensidad; __instance.buttonLight.color = estado.LuzColor; estado.LuzIntensidad = -1f; } estado.AvisoMostrado = false; return; } if ((Object)(object)__instance.buttonGrabObject != (Object)null && !((Behaviour)__instance.buttonGrabObject).enabled) { ((Behaviour)__instance.buttonGrabObject).enabled = true; Plugin.Debug("Boton del extractor reactivado (estaba desactivado)."); } if ((Object)(object)__instance.buttonLight != (Object)null && !((Behaviour)__instance.buttonLight).enabled) { ((Behaviour)__instance.buttonLight).enabled = true; } if (!estado.AvisoMostrado) { Plugin.Debug($"Meta cubierta ({___haulCurrent}/{__instance.haulGoal}). Esperando pulsacion. " + "buttonGrabObject=" + (((Object)(object)__instance.buttonGrabObject == (Object)null) ? "NULO" : "ok") + " buttonLight=" + (((Object)(object)__instance.buttonLight == (Object)null) ? "NULO" : "ok") + " pedestalRescatado=" + (((Object)(object)estado.Estacion == (Object)null) ? "NO" : "SI")); EncenderBoton(__instance, estado); } if (!AvisoEnPantalla.Value || estado.AvisoMostrado) { return; } estado.AvisoMostrado = true; try { _tubeScreenTextChange.Invoke(__instance, new object[2] { TextoPantalla.Value, Color.yellow }); } catch (Exception ex) { Plugin.Log.LogWarning((object)("No se pudo cambiar el texto del extractor: " + ex.Message)); } } } [HarmonyPatch(typeof(ExtractionPoint), "OnShopClick")] private static class BotonTiendaLanzaExtraccion { private static bool Prefix(ExtractionPoint __instance, PhotonView ___photonView, bool ___isShop) { if (!Enabled.Value) { return true; } if (___isShop) { return true; } if (EstadoDe(__instance).Esperando) { Solicitar(__instance, ___photonView); return false; } AvisarPorQueNoSePuede(EstadoDe(__instance)); return false; } } [HarmonyPatch(typeof(ExtractionPoint), "OnClick")] private static class BotonLanzaExtraccion { private static bool Prefix(ExtractionPoint __instance, PhotonView ___photonView) { if (!Enabled.Value) { return true; } if (__instance.isLocked) { return true; } if (!EstadoDe(__instance).Esperando) { return true; } Solicitar(__instance, ___photonView); return false; } } internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<bool> AvisoEnPantalla; internal static ConfigEntry<string> TextoPantalla; internal static ConfigEntry<bool> BotonGrande; internal static ConfigEntry<float> DesplazamientoX; internal static ConfigEntry<float> DesplazamientoY; internal static ConfigEntry<float> DesplazamientoZ; internal static ConfigEntry<bool> SoloElBoton; internal static ConfigEntry<float> EscalaBoton; internal static ConfigEntry<string> PiezasVisibles; internal static ConfigEntry<float> GiroBoton; internal static ConfigEntry<bool> UsarPato; internal static ConfigEntry<float> EscalaPato; internal static ConfigEntry<string> NombrePato; internal static ConfigEntry<float> GiroPatoX; internal static ConfigEntry<float> GiroPatoY; internal static ConfigEntry<float> GiroPatoZ; private static readonly ConditionalWeakTable<ExtractionPoint, Estado> _estados = new ConditionalWeakTable<ExtractionPoint, Estado>(); private const byte EventoPulsarBoton = 174; private static bool _redConectada; private static readonly MethodInfo _stateSet = AccessTools.Method(typeof(ExtractionPoint), "StateSet", (Type[])null, (Type[])null); private static readonly MethodInfo _tubeScreenTextChange = AccessTools.Method(typeof(ExtractionPoint), "TubeScreenTextChange", (Type[])null, (Type[])null); private static readonly FieldInfo _buttonOriginalMaterial = AccessTools.Field(typeof(ExtractionPoint), "buttonOriginalMaterial"); private const string MarcaPato = "RepoAmigos:BotonPato"; private static Item _itemPato; private static bool _patoBuscado; private static readonly ConditionalWeakTable<PhysGrabObject, Vinculo> _patos = new ConditionalWeakTable<PhysGrabObject, Vinculo>(); private static readonly FieldInfo _photonViewExtractor = AccessTools.Field(typeof(ExtractionPoint), "photonView"); private static float _ultimoAvisoPato = -10f; private static readonly HashSet<ItemEquippable> _equipablesDelPato = new HashSet<ItemEquippable>(); internal static void BindConfig(ConfigFile config) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Expected O, but got Unknown //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Expected O, but got Unknown Enabled = config.Bind<bool>("ExtraccionManual", "Activado", true, "Si esta activado, al cubrir la meta el extractor NO se dispara solo: espera a que alguien pulse el boton. Ponlo en false para volver al comportamiento original."); AvisoEnPantalla = config.Bind<bool>("ExtraccionManual", "AvisoEnPantalla", true, "Cambia el texto del tubo del extractor cuando ya esta listo, para que se vea que falta pulsarlo."); TextoPantalla = config.Bind<string>("ExtraccionManual", "TextoAviso", "PULSA EL BOTON", "Texto que aparece en el extractor cuando la meta ya esta cubierta."); BotonGrande = config.Bind<bool>("ExtraccionManual", "BotonGrandeDeTienda", true, "Conserva el pedestal con el boton grande que los extractores solo tienen en la tienda, y lo hace aparecer cuando la meta esta cubierta. En vanilla el juego lo destruye al arrancar cualquier nivel que no sea la tienda."); DesplazamientoX = config.Bind<float>("ExtraccionManual", "BotonLateral", 2.5f, new ConfigDescription("Mueve el boton grande a un lado u otro de la rampa, en metros.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-20f, 20f), Array.Empty<object>())); DesplazamientoY = config.Bind<float>("ExtraccionManual", "BotonAltura", 1.1f, new ConfigDescription("Altura del boton sobre el suelo de la rampa, en metros.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-20f, 20f), Array.Empty<object>())); UsarPato = config.Bind<bool>("ExtraccionManual", "UsarPato", true, "En vez del boton de la tienda, pone un pato de goma fijo al que agarrar para lanzar la extraccion. Mucho mas visible y no hay que pelearse con la geometria del mostrador."); NombrePato = config.Bind<string>("ExtraccionManual", "PatoNombreDelItem", "Rubber Duck", "Nombre exacto del item que se usa como boton. Si no lo encuentra, coge el primero que lleve 'duck' en el nombre. El log lista todos los disponibles."); GiroPatoX = config.Bind<float>("ExtraccionManual", "PatoGiroX", 0f, new ConfigDescription("Inclina el pato hacia delante o atras, en grados.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-360f, 360f), Array.Empty<object>())); GiroPatoY = config.Bind<float>("ExtraccionManual", "PatoGiroY", 0f, new ConfigDescription("Gira el pato sobre si mismo para que mire a donde quieras, en grados.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-360f, 360f), Array.Empty<object>())); GiroPatoZ = config.Bind<float>("ExtraccionManual", "PatoGiroZ", 0f, new ConfigDescription("Ladea el pato, en grados.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-360f, 360f), Array.Empty<object>())); EscalaPato = config.Bind<float>("ExtraccionManual", "PatoEscala", 2f, new ConfigDescription("Tamano del pato. 1 es su tamano normal.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 10f), Array.Empty<object>())); GiroBoton = config.Bind<float>("ExtraccionManual", "BotonGiro", 0f, new ConfigDescription("Gira el boton sobre si mismo, en grados. Prueba 180 si te da la espalda.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-360f, 360f), Array.Empty<object>())); DesplazamientoZ = config.Bind<float>("ExtraccionManual", "BotonHaciaFuera", 1f, new ConfigDescription("Aleja el boton grande del extractor (positivo) o lo acerca (negativo), en metros.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-20f, 20f), Array.Empty<object>())); SoloElBoton = config.Bind<bool>("ExtraccionManual", "SoloElBoton", true, "El pedestal de la tienda incluye el mostrador entero. Con esto activado solo se muestran las piezas indicadas en PiezasDelBoton y se oculta el resto."); PiezasVisibles = config.Bind<string>("ExtraccionManual", "PiezasDelBoton", "Extraction Point Side Button, Shop Button", "Piezas del pedestal que se dejan visibles, separadas por comas. Disponibles: 'Shop Button' (la placa roja, el boton en si), 'Extraction Point Side Button' (la consola sobre la que va montada la placa), 'Meshtownusa' y 'Cube (1)' (el mostrador de la tienda, un armatoste)."); EscalaBoton = config.Bind<float>("ExtraccionManual", "BotonEscala", 1f, new ConfigDescription("Tamano del boton. 0.5 lo deja a la mitad, 2 al doble.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); } private static Estado EstadoDe(ExtractionPoint punto) { return _estados.GetOrCreateValue(punto); } private static void AsegurarRed() { if (!_redConectada && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived += AlRecibirEvento; _redConectada = true; Plugin.Debug("Enganchado al canal de eventos de Photon."); } } internal static void DesconectarRed() { if (_redConectada) { if (PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= AlRecibirEvento; } _redConectada = false; } } private static void AlRecibirEvento(EventData datos) { if (datos.Code != 174 || !SemiFunc.IsMasterClient()) { return; } try { int num = (int)datos.CustomData; PhotonView val = PhotonView.Find(num); if (!((Object)(object)val == (Object)null)) { ExtractionPoint component = ((Component)val).GetComponent<ExtractionPoint>(); if (!((Object)(object)component == (Object)null) && EstadoDe(component).Esperando) { Plugin.Debug($"Peticion de extraccion recibida para el extractor {num}."); Ejecutar(component); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Error procesando el evento de extraccion: {arg}"); } } private static void Solicitar(ExtractionPoint punto, PhotonView view) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown punto.ButtonPress(); if (SemiFunc.IsMasterClientOrSingleplayer()) { Ejecutar(punto); return; } if ((Object)(object)view == (Object)null) { Plugin.Log.LogWarning((object)"Extractor sin PhotonView: no se puede avisar al master."); return; } PhotonNetwork.RaiseEvent((byte)174, (object)view.ViewID, new RaiseEventOptions { Receivers = (ReceiverGroup)2 }, SendOptions.SendReliable); Plugin.Debug($"No soy master: peticion enviada para el extractor {view.ViewID}."); } private static void Ejecutar(ExtractionPoint punto) { EstadoDe(punto).Armado = true; _stateSet.Invoke(punto, new object[1] { (object)(State)3 }); } private static void EncenderBoton(ExtractionPoint punto, Estado estado) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) try { object? obj = _buttonOriginalMaterial?.GetValue(punto); Material val = (Material)((obj is Material) ? obj : null); if ((Object)(object)val != (Object)null && (Object)(object)punto.button != (Object)null) { ((Renderer)punto.button).material = val; } if ((Object)(object)punto.buttonLight != (Object)null && estado.LuzIntensidad < 0f) { estado.LuzIntensidad = punto.buttonLight.intensity; estado.LuzColor = punto.buttonLight.color; punto.buttonLight.intensity = Mathf.Max(estado.LuzIntensidad * 3f, 5f); punto.buttonLight.color = Color.green; } if ((Object)(object)punto.buttonGrabObject != (Object)null) { Vector3 position = ((Component)punto.buttonGrabObject).transform.position; Vector3 position2 = ((Component)punto).transform.position; Plugin.Debug("Boton en " + ((Vector3)(ref position)).ToString("F1") + ", extractor en " + ((Vector3)(ref position2)).ToString("F1") + ", " + $"separacion {Vector3.Distance(position, position2):F1} m."); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("No se pudo encender el boton: " + ex.Message)); } } private static void DesplegarEstacion(Transform estacion, ExtractionPoint punto) { //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Expected O, but got Unknown //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Expected O, but got Unknown //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_0537: Unknown result type (might be due to invalid IL or missing references) //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Expected O, but got Unknown try { Transform[] componentsInChildren = ((Component)estacion).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } } int num = 0; int num2 = 0; Renderer[] componentsInChildren2 = ((Component)estacion).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren2) { num2++; if (!val2.enabled) { val2.enabled = true; num++; } } if (SoloElBoton.Value) { List<string> list = new List<string>(); string[] array = (PiezasVisibles.Value ?? "").Split(','); foreach (string text in array) { if (!string.IsNullOrEmpty(text.Trim())) { list.Add(text.Trim()); } } List<string> list2 = new List<string>(); foreach (Transform item in estacion) { Transform val3 = item; bool flag = false; foreach (string item2 in list) { if (string.Equals(item2, ((Object)val3).name, StringComparison.OrdinalIgnoreCase)) { flag = true; break; } } ((Component)val3).gameObject.SetActive(flag); if (!flag) { list2.Add(((Object)val3).name); } } componentsInChildren2 = ((Component)estacion).GetComponents<Renderer>(); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } if (list2.Count > 0) { Plugin.Debug("Mobiliario oculto: " + string.Join(", ", list2.ToArray())); } } estacion.localScale = Vector3.one * EscalaBoton.Value; Vector3 val4 = (((Object)(object)punto.ramp != (Object)null) ? punto.ramp.position : (((Object)(object)punto.platform != (Object)null) ? punto.platform.position : ((Component)punto).transform.position)); Vector3 val5 = val4 - ((Component)punto).transform.position; val5.y = 0f; val5 = ((((Vector3)(ref val5)).sqrMagnitude < 0.01f) ? ((Component)punto).transform.forward : ((Vector3)(ref val5)).normalized); Vector3 val6 = Vector3.Cross(Vector3.up, val5); estacion.rotation = Quaternion.LookRotation(val5, Vector3.up) * Quaternion.Euler(0f, GiroBoton.Value, 0f); Vector3 val7 = val4 + val6 * DesplazamientoX.Value + Vector3.up * DesplazamientoY.Value + val5 * DesplazamientoZ.Value; if (UsarPato.Value) { ((Component)estacion).gameObject.SetActive(false); CrearPato(EstadoDe(punto), val7); return; } Transform val8 = null; foreach (Transform item3 in estacion) { Transform val9 = item3; if (((Component)val9).gameObject.activeSelf && string.Equals(((Object)val9).name, "Shop Button", StringComparison.OrdinalIgnoreCase)) { val8 = val9; break; } } if ((Object)(object)val8 == (Object)null) { foreach (Transform item4 in estacion) { Transform val10 = item4; if (((Component)val10).gameObject.activeSelf) { val8 = val10; break; } } } Vector3 val11 = (((Object)(object)val8 != (Object)null) ? (val8.position - estacion.position) : Vector3.zero); estacion.position = val7 - val11; Plugin.Debug("Pieza de referencia: " + (((Object)(object)val8 == (Object)null) ? "ninguna" : ((Object)val8).name) + ", desfase=" + ((Vector3)(ref val11)).ToString("F2")); string[] obj = new string[8] { "Referencia: rampa=", null, null, null, null, null, null, null }; Vector3 val12; object obj2; if (!((Object)(object)punto.ramp == (Object)null)) { val12 = punto.ramp.position; obj2 = ((Vector3)(ref val12)).ToString("F1"); } else { obj2 = "NULA"; } obj[1] = (string)obj2; obj[2] = " plataforma="; object obj3; if (!((Object)(object)punto.platform == (Object)null)) { val12 = punto.platform.position; obj3 = ((Vector3)(ref val12)).ToString("F1"); } else { obj3 = "NULA"; } obj[3] = (string)obj3; obj[4] = " haciaFuera="; obj[5] = ((Vector3)(ref val5)).ToString("F2"); obj[6] = " lateral="; obj[7] = ((Vector3)(ref val6)).ToString("F2"); Plugin.Debug(string.Concat(obj)); string[] obj4 = new string[12] { "Pedestal '", ((Object)estacion).name, "': colocado en ", ((Vector3)(ref val7)).ToString("F1"), " (extractor en ", null, null, null, null, null, null, null }; val12 = ((Component)punto).transform.position; obj4[5] = ((Vector3)(ref val12)).ToString("F1"); obj4[6] = ") "; obj4[7] = $"activoEnJerarquia={((Component)estacion).gameObject.activeInHierarchy} "; obj4[8] = "escala="; val12 = estacion.lossyScale; obj4[9] = ((Vector3)(ref val12)).ToString("F2"); obj4[10] = " "; obj4[11] = $"renderers={num2} (reactivados {num}) hijos={estacion.childCount}"; Plugin.Debug(string.Concat(obj4)); foreach (Transform item5 in estacion) { Transform val13 = item5; Plugin.Debug($" hijo '{((Object)val13).name}' activo={((Component)val13).gameObject.activeSelf}"); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Fallo al desplegar el pedestal: " + ex.Message)); } } internal static void DesnudarPato(GameObject pato) { //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)pato == (Object)null) { return; } string[] array = new string[7] { "ItemRubberDuck", "HurtCollider", "ItemEquippable", "ItemBattery", "ItemToggle", "ParticleScriptExplosion", "ItemDeactivatedUntilLevel" }; MonoBehaviour[] componentsInChildren = pato.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } string name = ((object)val).GetType().Name; string[] array2 = array; foreach (string text in array2) { if (name == text) { Object.Destroy((Object)(object)val); break; } } } MapCustom[] componentsInChildren2 = pato.GetComponentsInChildren<MapCustom>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.Destroy((Object)(object)componentsInChildren2[i]); } ItemBattery[] componentsInChildren3 = pato.GetComponentsInChildren<ItemBattery>(true); foreach (ItemBattery val2 in componentsInChildren3) { if ((Object)(object)val2.batteryTransform != (Object)null) { ((Component)val2.batteryTransform).gameObject.SetActive(false); } } componentsInChildren = pato.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { string name2 = ((object)val3).GetType().Name; if (name2 == "BatteryUI" || name2 == "ItemEquipCube") { ((Component)val3).gameObject.SetActive(false); } } } componentsInChildren = pato.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val4 in componentsInChildren) { if (!((Object)(object)val4 == (Object)null)) { string name3 = ((object)val4).GetType().Name; if (name3 == "ItemEquipCube" || name3 == "BatteryUI") { Object.Destroy((Object)(object)((Component)val4).gameObject); } } } Animator[] componentsInChildren4 = pato.GetComponentsInChildren<Animator>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { ((Behaviour)componentsInChildren4[i]).enabled = false; } AudioSource[] componentsInChildren5 = pato.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource obj in componentsInChildren5) { obj.Stop(); ((Behaviour)obj).enabled = false; } ParticleSystem[] componentsInChildren6 = pato.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren6.Length; i++) { componentsInChildren6[i].Stop(); } TrailRenderer[] componentsInChildren7 = pato.GetComponentsInChildren<TrailRenderer>(true); for (int i = 0; i < componentsInChildren7.Length; i++) { ((Renderer)componentsInChildren7[i]).enabled = false; } ItemEquippable[] componentsInChildren8 = pato.GetComponentsInChildren<ItemEquippable>(true); foreach (ItemEquippable val5 in componentsInChildren8) { ((Behaviour)val5).enabled = false; _equipablesDelPato.Add(val5); } Plugin.Debug($"Pato: {_equipablesDelPato.Count} ItemEquippable silenciados."); Rigidbody[] componentsInChildren9 = pato.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody obj2 in componentsInChildren9) { obj2.isKinematic = true; obj2.useGravity = false; } RegistrarPato(pato); if (Plugin.VerboseLogging == null || !Plugin.VerboseLogging.Value) { return; } List<string> list = new List<string>(); Renderer[] componentsInChildren10 = pato.GetComponentsInChildren<Renderer>(true); foreach (Renderer val6 in componentsInChildren10) { if (val6.enabled && ((Component)val6).gameObject.activeInHierarchy) { list.Add(((Object)((Component)val6).gameObject).name + "(" + ((object)val6).GetType().Name + ")"); } } List<string> list2 = new List<string>(); componentsInChildren = pato.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val7 in componentsInChildren) { if ((Object)(object)val7 != (Object)null) { list2.Add(((object)val7).GetType().Name + "@" + ((Object)((Component)val7).gameObject).name); } } Plugin.Debug("Pato desnudado. Piezas visibles: " + string.Join(", ", list.ToArray())); Plugin.Debug("Componentes que quedan: " + string.Join(", ", list2.ToArray())); List<string> list3 = new List<string>(); ItemEquipCube[] array3 = Object.FindObjectsOfType<ItemEquipCube>(); foreach (ItemEquipCube val8 in array3) { float num = Vector3.Distance(((Component)val8).transform.position, pato.transform.position); if (!(num > 4f)) { Transform root = ((Component)val8).transform.root; bool flag = ((Component)val8).transform.IsChildOf(pato.transform); list3.Add($"'{((Object)((Component)val8).gameObject).name}' raiz='{((Object)root).name}' a {num:F1}m " + (flag ? "(del pato)" : "(AJENO)")); } } Plugin.Debug((list3.Count == 0) ? "No hay ningun ItemEquipCube cerca del pato." : ("Cubos de equipar cerca: " + string.Join(" | ", list3.ToArray()))); } private static void RegistrarPato(GameObject pato) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) PhysGrabObject component = pato.GetComponent<PhysGrabObject>(); if ((Object)(object)component == (Object)null) { return; } ExtractionPoint punto = null; float num = float.MaxValue; ExtractionPoint[] array = Object.FindObjectsOfType<ExtractionPoint>(); foreach (ExtractionPoint val in array) { float num2 = Vector3.Distance(((Component)val).transform.position, pato.transform.position); if (num2 < num) { num = num2; punto = val; } } if (_patos.TryGetValue(component, out var value)) { value.Punto = punto; } else { _patos.Add(component, new Vinculo { Punto = punto }); } Plugin.Debug($"Pato registrado, extractor mas cercano a {num:F1} m."); } private static void AvisarPorQueNoSePuede(Estado estado) { //IL_0078: 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) string text = ((!estado.Activo) ? "Este extractor todavia no esta activo" : (estado.MetaConocida ? $"Faltan {estado.FaltaBotin:N0} de botin" : "Espera, el extractor aun no ha pedido su botin")); if (!(Time.time - _ultimoAvisoPato < 1.5f)) { _ultimoAvisoPato = Time.time; Plugin.Debug("Pato pulsado y no se puede: " + text + "."); SemiFunc.UIFocusText(text, new Color(1f, 0.6f, 0.2f), Color.white, 3f); } } private static Item BuscarItemPato() { if (_patoBuscado) { return _itemPato; } _patoBuscado = true; string text = (NombrePato.Value ?? "").Trim(); try { List<Item> list = new List<Item>(); Item[] array = Resources.LoadAll<Item>(""); foreach (Item val in array) { if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(val.itemName)) { if (string.Equals(val.itemName, text, StringComparison.OrdinalIgnoreCase)) { _itemPato = val; break; } if (val.itemName.IndexOf("duck", StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(val); } } } if ((Object)(object)_itemPato == (Object)null && list.Count > 0) { _itemPato = list[0]; } if (list.Count > 0) { List<string> list2 = new List<string>(); foreach (Item item in list) { list2.Add("'" + item.itemName + "'"); } Plugin.Debug("Items tipo pato disponibles: " + string.Join(", ", list2.ToArray())); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Fallo buscando el item del pato: " + ex.Message)); } if ((Object)(object)_itemPato == (Object)null) { Plugin.Log.LogWarning((object)("No encontre ningun item llamado '" + text + "' ni con 'duck' en el nombre.")); } else { Plugin.Debug("Item del pato: '" + _itemPato.itemName + "' (buscaba '" + text + "')."); } return _itemPato; } private static void CrearPato(Estado estado, Vector3 posicion) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || (Object)(object)estado.Pato != (Object)null) { return; } Item val = BuscarItemPato(); if ((Object)(object)val == (Object)null || val.prefab == null) { return; } Quaternion val2 = val.spawnRotationOffset * Quaternion.Euler(GiroPatoX.Value, GiroPatoY.Value, GiroPatoZ.Value); GameObject val3; if (GameManager.instance.gameMode == 0) { val3 = Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)val.prefab).Prefab, posicion, val2); DesnudarPato(val3); } else { val3 = PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)val.prefab).ResourcePath, posicion, val2, (byte)0, new object[1] { "RepoAmigos:BotonPato" }); } if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"No se pudo crear el pato."); return; } Transform transform = val3.transform; transform.localScale *= EscalaPato.Value; estado.Pato = val3.GetComponent<PhysGrabObject>(); estado.PatoPosicion = posicion; estado.PatoRotacion = val2; if (Plugin.VerboseLogging != null && Plugin.VerboseLogging.Value) { List<string> list = new List<string>(); Component[] components = val3.GetComponents<Component>(); foreach (Component val4 in components) { if ((Object)(object)val4 != (Object)null) { list.Add(((object)val4).GetType().Name); } } Plugin.Debug("Prefab creado: '" + ((Object)val3).name + "' (ruta '" + ((PrefabRef<GameObject>)(object)val.prefab).ResourcePath + "'). Componentes: " + string.Join(", ", list.ToArray())); } Plugin.Debug("Pato colocado en " + ((Vector3)(ref posicion)).ToString("F1") + " (PhysGrabObject=" + (((Object)(object)estado.Pato == (Object)null) ? "NULO" : "ok") + ")."); } private static void RetirarPato(Estado estado) { if (!((Object)(object)estado.Pato == (Object)null) && SemiFunc.IsMasterClientOrSingleplayer()) { GameObject gameObject = ((Component)estado.Pato).gameObject; estado.Pato = null; if (SemiFunc.IsMultiplayer()) { PhotonNetwork.Destroy(gameObject); } else { Object.Destroy((Object)(object)gameObject); } Plugin.Debug("Pato retirado."); } } internal static void DestruirSalvoQueLoConservemos(Object objeto) { if (Enabled == null || !Enabled.Value || BotonGrande == null || !BotonGrande.Value) { Object.Destroy(objeto); } } } internal static class GeneradorDePruebas { [HarmonyPatch(typeof(RunManager), "Update")] private static class EngancheDeTeclado { private static bool _primeraVez = true; private static void Postfix() { if (_primeraVez) { _primeraVez = false; Plugin.Log.LogInfo((object)"Pruebas: RunManager.Update esta corriendo. Enganche OK."); } Tick("RunManager"); } } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] private static class SondaCambioDeNivel { private static void Postfix() { Plugin.Log.LogInfo((object)"Pruebas: sonda ChangeLevel ejecutada. Los parches SI corren."); } } internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyCode> Tecla; internal static ConfigEntry<int> ValorMin; internal static ConfigEntry<int> ValorMax; internal static ConfigEntry<int> Cantidad; private static bool _diagnosticoEscrito; private static int _teclasRegistradas; private static int _ultimoFrame = -1; private static readonly string[] _listasPorTamano = new string[3] { "smallValuables", "tinyValuables", "mediumValuables" }; internal static void BindConfig(ConfigFile config) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown Enabled = config.Bind<bool>("Pruebas", "Activado", true, "Permite generar objetos de valor con una tecla para probar el mod. Ponlo en false cuando juegues en serio."); Tecla = config.Bind<KeyCode>("Pruebas", "Tecla", (KeyCode)284, "Tecla que genera los objetos."); ValorMin = config.Bind<int>("Pruebas", "ValorMinimo", 2000, new ConfigDescription("Precio minimo de cada objeto generado.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000000), Array.Empty<object>())); ValorMax = config.Bind<int>("Pruebas", "ValorMaximo", 9000, new ConfigDescription("Precio maximo de cada objeto generado.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1000000), Array.Empty<object>())); Cantidad = config.Bind<int>("Pruebas", "CantidadPorPulsacion", 1, new ConfigDescription("Cuantos objetos salen con cada pulsacion.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); } private static bool TeclaPulsada() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) try { Keyboard current = Keyboard.current; if (current != null && Enum.TryParse<Key>(((object)Tecla.Value/*cast due to .constrained prefix*/).ToString(), ignoreCase: true, out Key result)) { KeyControl val = current[result]; if (val != null && ((ButtonControl)val).wasPressedThisFrame) { return true; } } } catch { } try { if (Input.GetKeyDown(Tecla.Value)) { return true; } } catch { } return false; } private static void EspiarTeclado() { //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_0043: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (Plugin.VerboseLogging == null || !Plugin.VerboseLogging.Value || _teclasRegistradas >= 25) { return; } try { Keyboard current = Keyboard.current; if (current == null || !((ButtonControl)current.anyKey).wasPressedThisFrame) { return; } Enumerator<KeyControl> enumerator = current.allKeys.GetEnumerator(); try { while (enumerator.MoveNext()) { KeyControl current2 = enumerator.Current; if (((ButtonControl)current2).wasPressedThisFrame) { _teclasRegistradas++; Plugin.Log.LogInfo((object)$"Pruebas: tecla pulsada = {current2.keyCode} (la configurada es {Tecla.Value})"); if (_teclasRegistradas >= 25) { Plugin.Log.LogInfo((object)"Pruebas: dejo de anotar teclas para no llenar el log."); break; } } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } catch { } } private static bool LegacyOperativo() { try { Input.GetKeyDown((KeyCode)294); return true; } catch { return false; } } internal static void Tick(string origen) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (Enabled == null || !Enabled.Value || Time.frameCount == _ultimoFrame) { return; } _ultimoFrame = Time.frameCount; if (!_diagnosticoEscrito) { _diagnosticoEscrito = true; bool flag = false; try { flag = Keyboard.current != null; } catch { } Plugin.Log.LogInfo((object)($"Pruebas: activo via {origen}. Tecla configurada = {Tecla.Value}. " + "InputSystem nuevo = " + (flag ? "SI" : "no") + ", Input clasico = " + (LegacyOperativo() ? "SI" : "no") + ".")); } EspiarTeclado(); if (!TeclaPulsada()) { return; } Plugin.Log.LogInfo((object)$"Pruebas: {Tecla.Value} detectada."); if (!SemiFunc.IsMasterClientOrSingleplayer()) { Plugin.Log.LogWarning((object)"F3: solo funciona si eres el anfitrion de la partida."); return; } if ((Object)(object)ValuableDirector.instance == (Object)null) { Plugin.Log.LogWarning((object)"F3: todavia no estas en un nivel."); return; } int num = 0; for (int i = 0; i < Cantidad.Value; i++) { if (Generar(i)) { num++; } } if (num > 0) { Plugin.Log.LogInfo((object)$"F3: generados {num} objeto(s) de prueba."); } } private static List<PrefabRef> ElegirLista() { string[] listasPorTamano = _listasPorTamano; foreach (string text in listasPorTamano) { FieldInfo fieldInfo = AccessTools.Field(typeof(ValuableDirector), text); if (!(fieldInfo == null) && fieldInfo.GetValue(ValuableDirector.instance) is List<PrefabRef> { Count: >0 } list) { return list; } } return null; } private static bool Generar(int indice) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar val = SemiFunc.PlayerAvatarLocal(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"F3: no encuentro al jugador local."); return false; } List<PrefabRef> list = ElegirLista(); if (list == null) { Plugin.Log.LogWarning((object)"F3: las listas de objetos del nivel estan vacias."); return false; } PrefabRef val2 = list[Random.Range(0, list.Count)]; Transform transform = ((Component)val).transform; float num = (float)indice * 0.9f; Vector3 val3 = new Vector3(Mathf.Sin(num), 0f, Mathf.Cos(num)) * 0.35f; Vector3 val4 = transform.position + transform.forward * 1.4f + Vector3.up * 1.1f + val3; GameObject val5 = ((GameManager.instance.gameMode != 0) ? PhotonNetwork.InstantiateRoomObject(((PrefabRef<GameObject>)(object)val2).ResourcePath, val4, Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)val2).Prefab, val4, Quaternion.identity)); if ((Object)(object)val5 == (Object)null) { Plugin.Log.LogWarning((object)("F3: no se pudo crear '" + ((PrefabRef<GameObject>)(object)val2).ResourcePath + "'.")); return false; } ValuableObject component = val5.GetComponent<ValuableObject>(); if ((Object)(object)component == (Object)null) { Plugin.Log.LogWarning((object)"F3: el prefab creado no tiene ValuableObject."); return false; } int num2 = Random.Range(ValorMin.Value, ValorMax.Value + 1); AccessTools.Field(typeof(ValuableObject), "dollarValueOverride").SetValue(component, num2); component.DollarValueSetLogic(); if (SemiFunc.IsMultiplayer()) { PhotonView component2 = val5.GetComponent<PhotonView>(); if ((Object)(object)component2 != (Object)null) { component2.RPC("DollarValueSetRPC", (RpcTarget)1, new object[1] { (float)num2 }); } } Plugin.Debug($"F3: '{((PrefabRef<GameObject>)(object)val2).PrefabName}' generado por ${num2}."); return true; } } internal static class ReviveEnExtractor { private sealed class Estado { public float Temporizador = -1f; public bool YaRevivido; } [HarmonyPatch(typeof(PlayerDeathHead), "Update")] private static class RevivirPorEstarDentro { private static void Postfix(PlayerDeathHead __instance, bool ___inExtractionPoint, bool ___triggered) { if (!Enabled.Value || !SemiFunc.IsMasterClientOrSingleplayer()) { return; } Estado orCreateValue = _estados.GetOrCreateValue(__instance); if (!___inExtractionPoint || !___triggered) { orCreateValue.Temporizador = Segundos.Value; orCreateValue.YaRevivido = false; } else if (!orCreateValue.YaRevivido) { if (orCreateValue.Temporizador < 0f) { orCreateValue.Temporizador = Segundos.Value; } orCreateValue.Temporizador -= Time.deltaTime; if (!(orCreateValue.Temporizador > 0f) && !((Object)(object)__instance.playerAvatar == (Object)null)) { orCreateValue.YaRevivido = true; Plugin.Debug("Reviviendo a " + ((Object)__instance.playerAvatar).name + " desde el extractor."); __instance.Revive(); } } } } internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> Segundos; private static readonly ConditionalWeakTable<PlayerDeathHead, Estado> _estados = new ConditionalWeakTable<PlayerDeathHead, Estado>(); internal static void BindConfig(ConfigFile config) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown Enabled = config.Bind<bool>("RevivirEnExtractor", "Activado", true, "Si esta activado, dejar la cabeza de un companero muerto dentro de un extractor lo revive tras unos segundos, sin necesidad de completar la extraccion."); Segundos = config.Bind<float>("RevivirEnExtractor", "SegundosDeEspera", 2f, new ConfigDescription("Tiempo que la cabeza debe permanecer dentro del extractor antes de revivir. El camion usa 2 segundos en vanilla.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>())); } } internal enum Rol : byte { Ninguno, Medico, Ingeniero, Saboteador, Rastreador } internal static class Roles { [HarmonyPatch(typeof(RunManager), "ChangeLevel")] private static class MarcarRepartoAlCambiarNivel { private static void Postfix() { ComprobacionDeVersion.AlCambiarNivel(); if (Enabled != null && Enabled.Value) { if (_repartoHecho && !RepartirCadaNivel.Value) { _esperaAnuncio = 4f; return; } _pendienteRepartir = true; _esperaReparto = 3f; Plugin.Debug("Roles: cambio de nivel, reparto pendiente."); } } } [HarmonyPatch(typeof(RunManager), "Update")] private static class TicPorFrame { private static void Postfix() { AsegurarRed(); ComprobacionDeVersion.Tick(); TicDelRecordatorio(); if (Enabled == null || !Enabled.Value) { return; } if (_pendienteRepartir) { IntentarRepartir(); } RevisarHuerfanos(); RedifundirDeVezEnCuando(); if (_esperaAnuncio > 0f) { _esperaAnuncio -= Time.deltaTime; if (_esperaAnuncio <= 0f) { _esperaAnuncio = -1f; Anunciar(); } } RolMedico.Tick(); RolIngeniero.Tick(); RolSaboteador.Tick(); RolRastreador.Tick(); } } internal enum EscribiendoResultado { No, Si, NoSePuedeSaber } internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> MinJugadores; internal static ConfigEntry<bool> RepartirCadaNivel; internal static ConfigEntry<bool> AnunciarRol; internal static ConfigEntry<bool> RecordarRol; internal static ConfigEntry<KeyCode> TeclaRecordar; internal static readonly Color ColorMedico = new Color(0.4f, 1f, 0.5f); internal static readonly Color ColorIngeniero = new Color(0.4f, 0.8f, 1f); internal static readonly Color ColorSaboteador = new Color(1f, 0.3f, 0.3f); internal static readonly Color ColorRastreador = new Color(1f, 0.85f, 0.3f); internal static readonly Color ColorSinRol = new Color(0.75f, 0.75f, 0.75f); private static readonly Dictionary<string, Rol> _asignados = new Dictionary<string, Rol>(); private static Rol _local = Rol.Ninguno; private static bool _repartoHecho; private static bool _pendienteRepartir; private static float _esperaReparto; private static float _esperaAnuncio = -1f; private static readonly FieldInfo _campoTemporizadorUI = AccessTools.Field(typeof(MissionUI), "messageTimer"); private static bool _recordatorioEnPantalla; private static readonly FieldInfo _campoChatActivo = AccessTools.Field(typeof(ChatManager), "chatActive"); internal const byte EventoReparto = 175; internal const byte EventoSabotaje = 176; internal const byte EventoApagon = 177; internal const byte EventoVersion = 178; internal const byte EventoRecarga = 179; private static bool _redConectada; private static float _proximaRevisionHuerfanos = 5f; private static float _proximaRedifusion = 20f; internal static Rol Local { get { if (Enabled == null || !Enabled.Value) { return Rol.Ninguno; } return _local; } } internal static event Action AlRepartir; internal static void BindConfig(ConfigFile config) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown Enabled = config.Bind<bool>("Roles", "Activado", true, "Reparte roles secretos (medico, ingeniero, saboteador, rastreador) al empezar cada nivel. Cada rol se activa ademas por su cuenta en su propia seccion."); MinJugadores = config.Bind<int>("Roles", "MinimoJugadores", 3, new ConfigDescription("Por debajo de esta cantidad de jugadores no se reparte ningun rol. Con dos personas un saboteador no tiene gracia.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); RepartirCadaNivel = config.Bind<bool>("Roles", "RepartirCadaNivel", true, "true: se vuelven a sortear los roles en cada nivel, asi todos van rotando. false: se sortean una vez y duran toda la partida."); AnunciarRol = config.Bind<bool>("Roles", "AnunciarRol", true, "Muestra en pantalla que rol te ha tocado al empezar el nivel. Solo lo ves tu: el reparto de los demas no se anuncia a nadie."); RecordarRol = config.Bind<bool>("Roles", "RecordarRol", true, "Permite volver a ver en cualquier momento que rol tienes y como se usa, pulsando la tecla de abajo. El aviso del principio del nivel se pierde enseguida y luego no habia forma de consultarlo."); TeclaRecordar = config.Bind<KeyCode>("Roles", "TeclaRecordar", (KeyCode)9, "Tecla que recuerda tu rol. Tab es tambien la del mapa del juego, asi que las dos cosas salen a la vez; no se pisan, pero se puede cambiar aqui."); } internal static bool SoyEl(Rol rol) { if (rol != Rol.Ninguno) { return Local == rol; } return false; } internal static bool RolEnJuego(Rol rol) { if (Enabled == null || !Enabled.Value) { return false; } List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { return false; } foreach (KeyValuePair<string, Rol> asignado in _asignados) { if (asignado.Value != rol) { continue; } foreach (PlayerAvatar item in list) { if (!((Object)(object)item == (Object)null) && SemiFunc.PlayerGetSteamID(item) == asignado.Key) { return true; } } } return false; } private static void IntentarRepartir() { _esperaReparto -= Time.deltaTime; if (!(_esperaReparto > 0f) && !((Object)(object)RunManager.instance == (Object)null) && SemiFunc.RunIsLevel() && !((Object)(object)PlayerAvatar.instance == (Object)null) && (!SemiFunc.IsMultiplayer() || PhotonNetwork.InRoom) && SemiFunc.IsMasterClientOrSingleplayer()) { Repartir(); } } private static void Repartir() { _pendienteRepartir = false; List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { _pendienteRepartir = true; _esperaReparto = 1f; return; } _asignados.Clear(); if (list.Count < MinJugadores.Value) { Plugin.Debug($"Roles: solo {list.Count} jugadores, minimo {MinJugadores.Value}. Sin roles."); Difundir(repartoNuevo: true); Aplicar(repartoNuevo: true); return; } List<Rol> list2 = new List<Rol>(); if (RolIngeniero.Enabled.Value) { list2.Add(Rol.Ingeniero); } if (RolMedico.Enabled.Value) { list2.Add(Rol.Medico); } if (RolSaboteador.Enabled.Value) { list2.Add(Rol.Saboteador); } if (RolRastreador.Enabled.Value) { list2.Add(Rol.Rastreador); } List<PlayerAvatar> list3 = new List<PlayerAvatar>(list); for (int num = list3.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); PlayerAvatar value = list3[num]; list3[num] = list3[index]; list3[index] = value; } int num2 = 0; for (int i = 0; i < list3.Count; i++) { if (num2 >= list2.Count) { break; } string text = SemiFunc.PlayerGetSteamID(list3[i]); if (!string.IsNullOrEmpty(text)) { _asignados[text] = list2[num2]; num2++; } } _repartoHecho = true; Plugin.Debug($"Roles: repartidos {num2} de {list2.Count} entre {list.Count} jugadores."); Difundir(repartoNuevo: true); Aplicar(repartoNuevo: true); } private static void Aplicar(bool repartoNuevo) { Rol local = _local; _local = Rol.Ninguno; PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance != (Object)null) { string text = SemiFunc.PlayerGetSteamID(instance); if (!string.IsNullOrEmpty(text) && _asignados.TryGetValue(text, out var value)) { _local = value; } } bool flag = _local != local; if (repartoNuevo || flag) { Plugin.Log.LogInfo((object)$"Roles: me ha tocado {_local}."); } if ((repartoNuevo || flag) && Roles.AlRepartir != null) { Roles.AlRepartir(); } if (repartoNuevo || flag) { _esperaAnuncio = (AnunciarRol.Value ? 2f : (-1f)); } } private static void Anunciar() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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) switch (_local) { case Rol.Medico: SemiFunc.UIBigMessage("ERES EL MEDICO", "+", 40f, new Color(0.4f, 1f, 0.5f), Color.white); RolMedico.AvisarUso(); break; case Rol.Ingeniero: SemiFunc.UIBigMessage("ERES EL INGENIERO", "*", 40f, new Color(0.4f, 0.8f, 1f), Color.white); RolIngeniero.AvisarUso(); break; case Rol.Saboteador: SemiFunc.UIBigMessage("ERES EL SABOTEADOR", "!", 40f, new Color(1f, 0.3f, 0.3f), Color.white); RolSaboteador.AvisarUso(); break; case Rol.Rastreador: SemiFunc.UIBigMessage("ERES EL RASTREADOR", "?", 40f, new Color(1f, 0.85f, 0.3f), Color.white); RolRastreador.AvisarUso(); break; } } private static string TextoDelRecordatorio(out Color color) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: 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) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (Enabled != null && Enabled.Value) { switch (_local) { case Rol.Medico: color = ColorMedico; return "ERES EL MEDICO - " + RolMedico.TextoDeUso(); case Rol.Ingeniero: color = ColorIngeniero; return "ERES EL INGENIERO - " + RolIngeniero.TextoDeUso(); case Rol.Saboteador: color = ColorSaboteador; return "ERES EL SABOTEADOR - " + RolSaboteador.TextoDeUso(); case Rol.Rastreador: color = ColorRastreador; return "ERES EL RASTREADOR - " + RolRastreador.TextoDeUso(); } } color = ColorSinRol; if (Enabled == null || !Enabled.Value) { return "SIN ROL - los roles estan desactivados en la configuracion"; } if (!_repartoHecho) { return "SIN ROL - todavia no se han repartido los roles de este nivel"; } int num = SemiFunc.PlayerGetAll()?.Count ?? 0; if (num >= MinJugadores.Value) { return "SIN ROL - este nivel no te ha tocado ningun rol"; } return $"SIN ROL - hacen falta {MinJugadores.Value} jugadores y sois {num}"; } private static bool MantenerAvisoVivo(float segundos) { if (_campoTemporizadorUI == null) { return false; } MissionUI instance = MissionUI.instance; if ((Object)(object)instance == (Object)null) { return false; } _campoTemporizadorUI.SetValue(instance, segundos); return true; } private static void TicDelRecordatorio() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (RecordarRol == null || !RecordarRol.Value) { return; } if (!EnPartida()) { _recordatorioEnPantalla = false; } else if (TeclaPulsada(TeclaRecordar.Value)) { SemiFunc.UIFocusText(TextoDelRecordatorio(out var color), color, Color.white, 0.4f); _recordatorioEnPantalla = true; } else if (_recordatorioEnPantalla) { if (TeclaMantenida(TeclaRecordar.Value)) { MantenerAvisoVivo(0.4f); } else { _recordatorioEnPantalla = false; } } } internal static EscribiendoResultado Escribiendo() { if (_campoChatActivo == null) { return EscribiendoResultado.NoSePuedeSaber; } ChatManager instance = ChatManager.instance; if ((Object)(object)instance == (Object)null) { return EscribiendoResultado.No; } object value = _campoChatActivo.GetValue(instance); if (!(value is bool)) { return EscribiendoResultado.NoSePuedeSaber; } if (!(bool)value) { return EscribiendoResultado.No; } return EscribiendoResultado.Si; } internal unsafe static bool TeclaMantenida(KeyCode tecla) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (Escribiendo() == EscribiendoResultado.Si) { return false; } try { Keyboard current = Keyboard.current; if (current != null && Enum.TryParse<Key>(((object)(*(KeyCode*)(&tecla))/*cast due to .constrained prefix*/).ToString(), ignoreCase: true, out Key result)) { KeyControl val = current[result]; if (val != null && ((ButtonControl)val).isPressed) { return true; } } } catch { } try { if (Input.GetKey(tecla)) { return true; } } catch { } return false; } internal unsafe static bool TeclaPulsada(KeyCode tecla) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (Escribiendo() == EscribiendoResultado.Si) { return false; } try { Keyboard current = Keyboard.current; if (current != null && Enum.TryParse<Key>(((object)(*(KeyCode*)(&tecla))/*cast due to .constrained prefix*/).ToString(), ignoreCase: true, out Key result)) { KeyControl val = current[result]; if (val != null && ((ButtonControl)val).wasPressedThisFrame) { return true; } } } catch { } try { if (Input.GetKeyDown(tecla)) { return true; } } catch { } return false; } internal static bool EnPartida() { if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)PlayerAvatar.instance != (Object)null) { return SemiFunc.RunIsLevel(); } return false; } private static void AsegurarRed() { if (!_redConectada && PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= AlRecibirEvento; PhotonNetwork.NetworkingClient.EventReceived += AlRecibirEvento; _redConectada = true; Plugin.Debug("Roles: enganchado al canal de eventos de Photon."); } } internal static void DesconectarRed() { if (_redConectada) { if (PhotonNetwork.NetworkingClient != null) { PhotonNetwork.NetworkingClient.EventReceived -= AlRecibirEvento; } _redConectada = false; } } private static void AlRecibirEvento(EventData datos) { try { switch (datos.Code) { case 175: RecibirReparto(datos.CustomData); break; case 176: if (SemiFunc.IsMasterClient()) { RolSaboteador.EjecutarBoostEnemigos(datos.CustomData); } break; case 177: RolSaboteador.EjecutarApagon(datos.CustomData); break; case 178: ComprobacionDeVersion.Recibir(datos.CustomData); break; case 179: if (SemiFunc.IsMasterClient()) { RolIngeniero.EjecutarRecargaRemota(datos.CustomData); } break; } } catch (Exception arg) { Plugin.Log.LogError((object)($"Roles: fallo procesando el evento {datos.Code}. " + $"Se ignora para no tumbar la conexion.\n{arg}")); } } private static void RevisarHuerfanos() { if (!_repartoHecho || !SemiFunc.IsMasterClientOrSingleplayer() || !EnPartida()) { return; } _proximaRevisionHuerfanos -= Time.deltaTime; if (_proximaRevisionHuerfanos > 0f) { return; } _proximaRevisionHuerfanos = 5f; List<PlayerAvatar> list = SemiFunc.PlayerGetAll(); if (list == null || list.Count == 0) { return; } List<string> list2 = new List<string>(); foreach (PlayerAvatar item in list) { if (!((Object)(object)item == (Object)null)) { string text = SemiFunc.PlayerGetSteamID(item); if (!string.IsNullOrEmpty(text)) { list2.Add(text); } } } if (list2.Count == 0) { return; } List<string> list3 = new List<string>(); List<Rol> list4 = new List<Rol>(); foreach (KeyValuePair<string, Rol> asignado in _asignados) { if (!list2.Contains(asignado.Key)) { list3.Add(asignado.Key); list4.Add(asignado.Value); } } if (list3.Count == 0) { return; } foreach (string item2 in list3) { _asignados.Remove(item2); } List<string> list5 = new List<string>(); foreach (string item3 in list2) { if (!_asignados.ContainsKey(item3)) { list5.Add(item3); } } list4.Sort((Rol a, Rol b) => Prioridad(a).CompareTo(Prioridad(b))); int num = 0; for (int num2 = 0; num2 < list4.Count && num2 < list5.Count; num2++) { _asignados[list5[num2]] = list4[num2]; num++; } Plugin.Log.LogInfo((object)($"Roles: {list3.Count} rol(es) sin dueno tras una desconexion. " + $"Reasignados {num}, descartados {list4.Count - num}.")); Difundir(repartoNuevo: false); Aplicar(repartoNuevo: false); } private static int Prioridad(Rol rol) { return rol switch { Rol.Ingeniero => 0, Rol.Medico => 1, Rol.Saboteador => 2, _ => 3, }; } private static void RedifundirDeVezEnCuando() { if (_repartoHecho && SemiFunc.IsMasterClient()) { _proximaRedifusion -= Time.deltaTime; if (!(_proximaRedifusion > 0f)) { _proximaRedifusion = 20f; Difundir(repartoNuevo: false); } } } private static void Difundir(bool repartoNuevo) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown if (!SemiFunc.IsMultiplayer() || PhotonNetwork.NetworkingClient == null) { return; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(repartoNuevo ? 'N' : 'R').Append('|'); bool flag = true; foreach (KeyValuePair<string, Rol> asignado in _asignados) { if (!flag) { stringBuilder.Append(';'); } flag = false; stringBuilder.Append(asignado.Key).Append(':').Append((byte)asignado.Value); } PhotonNetwork.RaiseEvent((byte)175, (object)stringBuilder.ToString(), new RaiseEventOptions { Receivers = (ReceiverGroup)0 }, SendOptions.SendReliable); } private static void RecibirReparto(object datos) { if (!(datos is string text)) { return; } int num = text.IndexOf('|'); if (num < 0) { return; } bool repartoNuevo = text.Substring(0, num) == "N"; string text2 = text.Substring(num + 1); Dictionary<string, Rol> dictionary = new Dictionary<string, Rol>(); if (text2.Length > 0) { string[] array = text2.Split(';'); foreach (string text3 in array) { int num2 = text3.LastIndexOf(':'); if (num2 > 0 && num2 != text3.Length - 1 && byte.TryParse(text3.Substring(num2 + 1), out var result)) { dictionary[text3.Substring(0, num2)] = (Rol)result; } } } if (EsElMismoReparto(dictionary)) { return; } _asignados.Clear(); foreach (KeyValuePair<string, Rol> item in dictionary) { _asignados[item.Key] = item.Value; } _repartoHecho = true; Aplicar(repartoNuevo); } private static bool EsElMismoReparto(Dictionary<string, Rol> otro) { if (!_repartoHecho) { return false; } if (_asignados.Count != otro.Count) { return false; } foreach (KeyValuePair<string, Rol> item in otro) { if (!_asignados.TryGetValue(item.Key, out var value)) { return false; } if (value != item.Value) { return false; } } return true; } } internal static class RolIngeniero { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyCode> Tecla; internal static ConfigEntry<int> Cargas; internal static ConfigEntry<float> MinutosRecarga; private static int _cargas; private static float _temporizador; private static readonly FieldInfo _campoAgarrado = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject"); internal static void BindConfig(ConfigFile config) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Enabled = config.Bind<bool>("Ingeniero", "Activado", true, "Mete el rol de ingeniero en el sorteo. El ingeniero recarga la bateria del objeto que lleve en las manos."); Tecla = config.Bind<KeyCode>("Ingeniero", "Tecla", (KeyCode)106, "Tecla que recarga a tope el objeto que tengas agarrado."); config.Remove(new ConfigDefinition("Ingeniero", "AvisarAlRechazar")); Cargas = config.Bind<int>("Ingeniero", "Cargas", 5, new ConfigDescription("Reparaciones disponibles a la vez.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>())); MinutosRecarga = config.Bind<float>("Ingeniero", "MinutosRecarga", 5f, new ConfigDescription("Cada cuantos minutos se recupera UNA reparacion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>())); Roles.AlRepartir += delegate { if (Roles.SoyEl(Rol.Ingeniero)) { Reiniciar(); } }; } internal static void Reiniciar() { _cargas = Cargas.Value; _temporizador = MinutosRecarga.Value * 60f; } internal static string TextoDeUso() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return $"[{Tecla.Value}] recargar lo que lleves en las manos - {_cargas}/{Cargas.Value} reparaciones"; } internal static void AvisarUso() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) SemiFunc.UIFocusText(TextoDeUso(), Roles.ColorIngeniero, Color.white, 5f); } private static PhysGrabObject LoQueLlevoEnLasManos() { PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance == (Object)null || !instance.grabbed) { return null; } if (_campoAgarrado == null) { return null; } object? value = _campoAgarrado.GetValue(instance); return (PhysGrabObject)((value is PhysGrabObject) ? value : null); } internal static void Tick() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (Enabled != null && Enabled.Value && Roles.SoyEl(Rol.Ingeniero) && Roles.EnPartida()) { RecargarCargas(); if (Roles.TeclaPulsada(Tecla.Value)) { Reparar(); } } } private static void RecargarCargas() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (_cargas < Cargas.Value) { _temporizador -= Time.deltaTime; if (!(_temporizador > 0f)) { _cargas++; _temporizador = MinutosRecarga.Value * 60f; SemiFunc.UIFocusText($"Reparacion recuperada ({_cargas}/{Cargas.Value})", new Color(0.4f, 0.8f, 1f), Color.white, 3f); Plugin.Debug($"Ingeniero: reparacion recuperada, ahora {_cargas}/{Cargas.Value}. " + $"Siguiente en {MinutosRecarga.Value * 60f:0} s."); } } } private static void Reparar() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: 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) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) Color val = default(Color); ((Color)(ref val))..ctor(0.4f, 0.8f, 1f); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.6f, 0.2f); if (_cargas <= 0) { int num = Mathf.CeilToInt(_temporizador); SemiFunc.UIFocusText($"Sin reparaciones - {num / 60}:{num % 60:00} para la siguiente", val2, Color.white, 3f); return; } PhysGrabObject val3 = LoQueLlevoEnLasManos(); if ((Object)(object)val3 == (Object)null) { SemiFunc.UIFocusText("Agarra algo para repararlo", val2, Color.white, 2f); return; } ItemBattery componentInChildren = ((Component)val3).GetComponentInChildren<ItemBattery>(true); if ((Object)(object)componentInChildren == (Object)null) {