using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Serializing;
using FishNet.Transporting;
using HTF.Shared;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("HTFHollowPurple")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.2.0.0")]
[assembly: AssemblyInformationalVersion("3.2.0")]
[assembly: AssemblyProduct("HTFHollowPurple")]
[assembly: AssemblyTitle("HTFHollowPurple")]
[assembly: AssemblyVersion("3.2.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 HTF.Shared
{
internal static class AudioLoading
{
internal static readonly string[] SupportedExtensions = new string[3] { ".ogg", ".wav", ".mp3" };
internal static bool IsSupported(string path)
{
string ext = Path.GetExtension(path);
return Array.Exists(SupportedExtensions, (string e) => string.Equals(e, ext, StringComparison.OrdinalIgnoreCase));
}
internal static AudioType TypeOf(string path)
{
return (AudioType)(Path.GetExtension(path)?.ToLowerInvariant() switch
{
".ogg" => 14,
".wav" => 20,
".mp3" => 13,
_ => 0,
});
}
internal static IEnumerator Load(string source, bool stream, Action<AudioClip> onLoaded, Action<string> onError)
{
bool isRemote = source.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || source.StartsWith("https://", StringComparison.OrdinalIgnoreCase);
string text;
if (isRemote)
{
text = source;
}
else
{
if (!File.Exists(source))
{
onError?.Invoke("No existe el archivo: " + source);
yield break;
}
text = new Uri(Path.GetFullPath(source)).AbsoluteUri;
}
AudioType val = TypeOf(source);
if ((int)val == 0)
{
onError?.Invoke("Formato no soportado: " + source);
yield break;
}
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(text, val);
try
{
DownloadHandler downloadHandler = request.downloadHandler;
DownloadHandlerAudioClip val2 = (DownloadHandlerAudioClip)(object)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null);
if (val2 != null)
{
val2.streamAudio = stream || isRemote;
val2.compressed = false;
}
yield return request.SendWebRequest();
if ((int)request.result != 1)
{
onError?.Invoke(request.error + " (" + source + ")");
yield break;
}
AudioClip content;
try
{
content = DownloadHandlerAudioClip.GetContent(request);
}
catch (Exception ex)
{
onError?.Invoke(ex.Message + " (" + source + ")");
yield break;
}
if ((Object)(object)content == (Object)null || (int)content.loadState == 3)
{
onError?.Invoke("Unity no pudo descodificar " + Path.GetFileName(source) + ". Si es un MP3 con etiquetas raras, reexpórtalo a OGG.");
yield break;
}
((Object)content).name = (isRemote ? source : Path.GetFileNameWithoutExtension(source));
onLoaded?.Invoke(content);
}
finally
{
((IDisposable)request)?.Dispose();
}
}
}
}
namespace HTFHollowPurple
{
internal static class Hands
{
private static bool _resolved;
private static MethodInfo _setIkTarget;
private static MethodInfo _moveToDefault;
private static Type _armsType;
private static Component _arms;
private static Transform _rightTarget;
private static Transform _leftTarget;
private static bool _posing;
private static void Resolve()
{
if (_resolved)
{
return;
}
_resolved = true;
string[] array = new string[2] { "PlayerArms", "PlayerHands" };
for (int i = 0; i < array.Length; i++)
{
Type type = AccessTools.TypeByName(array[i]);
if (!(type == null))
{
MethodInfo methodInfo = AccessTools.Method(type, "SetIKTarget", (Type[])null, (Type[])null);
if (!(methodInfo == null))
{
_armsType = type;
_setIkTarget = methodInfo;
_moveToDefault = AccessTools.Method(type, "MoveHandToDefault", (Type[])null, (Type[])null);
break;
}
}
}
if (_setIkTarget == null)
{
Plugin.Log.LogInfo((object)"Sin cinemática inversa de manos: el disparo no tendrá pose.");
}
}
private static Component GetArms()
{
if ((Object)(object)_arms != (Object)null)
{
return _arms;
}
if (_armsType == null)
{
return null;
}
Object obj = Object.FindObjectOfType(_armsType);
_arms = (Component)(object)((obj is Component) ? obj : null);
return _arms;
}
internal static void Extend(Transform camera)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
Resolve();
if (_setIkTarget == null || !Plugin.PoseHands.Value || _posing)
{
return;
}
Component arms = GetArms();
if ((Object)(object)arms == (Object)null)
{
return;
}
_rightTarget = MakeTarget(camera, new Vector3(0.28f, -0.18f, 0.85f), "PurpleIKRight");
_leftTarget = MakeTarget(camera, new Vector3(-0.28f, -0.18f, 0.85f), "PurpleIKLeft");
try
{
_setIkTarget.Invoke(arms, new object[2] { _rightTarget, _leftTarget });
_posing = true;
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("No pude posar las manos: " + (ex.InnerException?.Message ?? ex.Message)));
Release();
}
}
internal static void Push(float t)
{
//IL_004d: 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)
if (_posing)
{
float num = Mathf.Lerp(0.85f, 1.35f, Mathf.Clamp01(t));
float num2 = Mathf.Lerp(0.28f, 0.1f, Mathf.Clamp01(t));
if ((Object)(object)_rightTarget != (Object)null)
{
_rightTarget.localPosition = new Vector3(num2, -0.18f, num);
}
if ((Object)(object)_leftTarget != (Object)null)
{
_leftTarget.localPosition = new Vector3(0f - num2, -0.18f, num);
}
}
}
internal static void Release()
{
_posing = false;
Component arms = GetArms();
if ((Object)(object)arms != (Object)null && _setIkTarget != null)
{
try
{
_setIkTarget.Invoke(arms, new object[2]);
}
catch
{
}
if (_moveToDefault != null)
{
try
{
_moveToDefault.Invoke(arms, new object[1] { true });
_moveToDefault.Invoke(arms, new object[1] { false });
}
catch
{
}
}
}
if ((Object)(object)_rightTarget != (Object)null)
{
Object.Destroy((Object)(object)((Component)_rightTarget).gameObject);
}
if ((Object)(object)_leftTarget != (Object)null)
{
Object.Destroy((Object)(object)((Component)_leftTarget).gameObject);
}
_rightTarget = null;
_leftTarget = null;
}
private static Transform MakeTarget(Transform camera, Vector3 offset, string name)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject(name);
val.transform.SetParent(camera, false);
val.transform.localPosition = offset;
val.transform.localRotation = Quaternion.identity;
return val.transform;
}
}
internal static class Aim
{
private static Camera _cached;
private static bool _logged;
internal static Camera GetCamera()
{
if ((Object)(object)_cached != (Object)null && ((Behaviour)_cached).isActiveAndEnabled)
{
return _cached;
}
_cached = Camera.main;
if ((Object)(object)_cached == (Object)null)
{
Type type = AccessTools.TypeByName("PlayerCamera");
if (type != null)
{
Object obj = Object.FindObjectOfType(type);
Component val = (Component)(object)((obj is Component) ? obj : null);
if ((Object)(object)val != (Object)null)
{
_cached = val.GetComponentInChildren<Camera>(true);
}
}
}
if ((Object)(object)_cached == (Object)null)
{
_cached = (from c in Camera.allCameras
where (Object)(object)c != (Object)null && ((Behaviour)c).isActiveAndEnabled
orderby c.depth descending
select c).FirstOrDefault();
}
if ((Object)(object)_cached != (Object)null && !_logged)
{
_logged = true;
Plugin.Log.LogInfo((object)("Cámara encontrada: " + ((Object)_cached).name));
}
return _cached;
}
}
internal static class Sounds
{
private static readonly string[] Extensions = new string[3] { ".mp3", ".ogg", ".wav" };
internal static string Find(string nameWithoutExtension)
{
if (string.IsNullOrEmpty(nameWithoutExtension))
{
return null;
}
string pluginPath = Paths.PluginPath;
if (!Directory.Exists(pluginPath))
{
return null;
}
try
{
return Directory.GetDirectories(pluginPath, "Sounds", SearchOption.AllDirectories).SelectMany((string dir) => Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories)).FirstOrDefault((string file) => string.Equals(Path.GetFileNameWithoutExtension(file), nameWithoutExtension, StringComparison.OrdinalIgnoreCase) && Extensions.Contains(Path.GetExtension(file).ToLowerInvariant()));
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("No pude buscar el sonido: " + ex.Message));
return null;
}
}
}
internal static class Held
{
internal static readonly List<object> Items = new List<object>();
private static bool _resolved;
private static PropertyInfo _holder;
private static MethodInfo _getName;
private static FieldInfo _localPlayer;
private static void Resolve()
{
if (!_resolved)
{
_resolved = true;
Type type = AccessTools.TypeByName("Item");
Type type2 = AccessTools.TypeByName("Player");
if (type != null)
{
_holder = AccessTools.Property(type, "Holder");
_getName = AccessTools.Method(type, "GetName", (Type[])null, (Type[])null);
}
if (type2 != null)
{
_localPlayer = AccessTools.Field(type2, "LocalPlayer");
}
}
}
internal static string CurrentName()
{
Resolve();
if (_holder == null || _localPlayer == null)
{
return null;
}
object value = _localPlayer.GetValue(null);
if (value == null)
{
return null;
}
Items.RemoveAll(delegate(object i)
{
if (i != null)
{
Object val = (Object)((i is Object) ? i : null);
if (val != null)
{
return val == (Object)null;
}
return false;
}
return true;
});
foreach (object item in Items)
{
object value2;
try
{
value2 = _holder.GetValue(item);
}
catch
{
continue;
}
if (value2 != value)
{
continue;
}
try
{
string text = _getName?.Invoke(item, null) as string;
if (!string.IsNullOrEmpty(text))
{
return text;
}
}
catch
{
}
object obj3 = ((item is Component) ? item : null);
return (obj3 != null) ? ((Object)((Component)obj3).gameObject).name : null;
}
return null;
}
internal static bool Allowed()
{
string value = Plugin.RequiredItem.Value;
string text = CurrentName();
Plugin.Log.LogInfo((object)("En la mano: " + (text ?? "nada")));
if (string.IsNullOrWhiteSpace(value))
{
return true;
}
if (text == null)
{
return false;
}
return text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0;
}
}
[HarmonyPatch]
internal static class ItemAwakePatch
{
private static MethodBase TargetMethod()
{
Type type = AccessTools.TypeByName("Item");
if (!(type == null))
{
return AccessTools.Method(type, "Awake", (Type[])null, (Type[])null);
}
return null;
}
private static bool Prepare()
{
return TargetMethod() != null;
}
private static void Postfix(object __instance)
{
if (__instance != null && !Held.Items.Contains(__instance))
{
Held.Items.Add(__instance);
}
}
}
public struct PurpleShot : IBroadcast
{
public Vector3 Origin;
public Vector3 Direction;
public float Range;
public float Radius;
}
internal static class Net
{
private static bool _serializers;
private static bool _clientReady;
private static bool _serverReady;
private static bool _broken;
internal static bool IsHost => InstanceFinder.IsServerStarted;
internal static void EnsureSerializers()
{
if (_serializers || _broken)
{
return;
}
try
{
GenericWriter<PurpleShot>.SetWrite((Action<Writer, PurpleShot>)delegate(Writer writer, PurpleShot value)
{
writer.WritePurpleShot(value);
});
GenericReader<PurpleShot>.SetRead((Func<Reader, PurpleShot>)((Reader reader) => reader.ReadPurpleShot()));
_serializers = true;
}
catch (Exception ex)
{
_broken = true;
Plugin.Log.LogWarning((object)("Sin red: " + ex.Message + ". Solo funcionará como anfitrión."));
}
}
internal static void Tick()
{
if (_broken)
{
return;
}
if (!_clientReady && (Object)(object)InstanceFinder.ClientManager != (Object)null)
{
try
{
InstanceFinder.ClientManager.RegisterBroadcast<PurpleShot>((Action<PurpleShot, Channel>)OnClientReceived);
_clientReady = true;
}
catch (Exception e)
{
Fail(e);
return;
}
}
if (_serverReady || !((Object)(object)InstanceFinder.ServerManager != (Object)null))
{
return;
}
try
{
InstanceFinder.ServerManager.RegisterBroadcast<PurpleShot>((Action<NetworkConnection, PurpleShot, Channel>)OnServerReceived, true);
_serverReady = true;
}
catch (Exception e2)
{
Fail(e2);
}
}
private static void Fail(Exception e)
{
_broken = true;
Plugin.Log.LogWarning((object)("No pude registrar la red: " + e.Message));
}
internal static void Fire(Vector3 origin, Vector3 direction, float range, float radius)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: 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)
PurpleShot purpleShot = new PurpleShot
{
Origin = origin,
Direction = direction,
Range = range,
Radius = radius
};
if (IsHost)
{
Execute(purpleShot, null);
return;
}
if (_broken || !_clientReady)
{
Plugin.Log.LogInfo((object)"Sin conexión con el servidor: verás el rayo, pero no matará nada.");
return;
}
try
{
InstanceFinder.ClientManager.Broadcast<PurpleShot>(purpleShot, (Channel)0);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("No pude enviar el disparo: " + ex.Message));
}
}
private static void OnServerReceived(NetworkConnection sender, PurpleShot shot, Channel channel)
{
Execute(shot, sender);
}
private static void OnClientReceived(PurpleShot shot, Channel channel)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
if (!IsHost)
{
Effects.SpawnOrb(shot.Origin, shot.Direction, Plugin.ParseColor(Plugin.BeamColor.Value), dealsDamage: false);
}
}
private static void Execute(PurpleShot shot, NetworkConnection sender)
{
if (!_serverReady)
{
return;
}
try
{
InstanceFinder.ServerManager.Broadcast<PurpleShot>(shot, true, (Channel)0);
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("No pude reenviar el disparo: " + ex.Message));
}
}
}
public static class PurpleShotSerializer
{
public static void WritePurpleShot(this Writer writer, PurpleShot value)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
if (writer != null)
{
writer.WriteVector3(value.Origin);
writer.WriteVector3(value.Direction);
writer.WriteSingle(value.Range);
writer.WriteSingle(value.Radius);
}
}
public static PurpleShot ReadPurpleShot(this Reader reader)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
return new PurpleShot
{
Origin = reader.ReadVector3(),
Direction = reader.ReadVector3(),
Range = reader.ReadSingle(),
Radius = reader.ReadSingle()
};
}
}
internal class Orb : MonoBehaviour
{
internal Vector3 Direction;
internal float Speed;
internal float Range;
internal float Radius;
internal bool DealsDamage;
private float _travelled;
private Light _light;
private readonly HashSet<object> _alreadyHit = new HashSet<object>();
private void Start()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
_light = ((Component)this).gameObject.AddComponent<Light>();
_light.color = (((Object)(object)((Component)this).GetComponent<Renderer>() != (Object)null) ? ((Component)this).GetComponent<Renderer>().material.color : Color.magenta);
_light.range = Radius * 8f;
_light.intensity = 14f;
}
private void Update()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: 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_0078: 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_009e: Unknown result type (might be due to invalid IL or missing references)
float num = Speed * Time.deltaTime;
Transform transform = ((Component)this).transform;
transform.position += Direction * num;
_travelled += num;
float num2 = 1f + _travelled / Mathf.Max(1f, Range) * 0.6f;
((Component)this).transform.localScale = Vector3.one * Radius * num2;
if (DealsDamage)
{
Annihilate.At(((Component)this).transform.position, Radius * num2, Direction, _alreadyHit);
}
if (_travelled >= Range)
{
Burst();
}
}
private void Burst()
{
if ((Object)(object)_light != (Object)null)
{
_light.intensity = 30f;
}
((Component)this).gameObject.AddComponent<OrbFade>().Seconds = 0.45f;
Object.Destroy((Object)(object)this);
}
}
internal class OrbFade : MonoBehaviour
{
internal float Seconds = 0.45f;
private float _elapsed;
private Vector3 _startScale;
private Renderer _renderer;
private Light _light;
private void Start()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
_startScale = ((Component)this).transform.localScale;
_renderer = ((Component)this).GetComponent<Renderer>();
_light = ((Component)this).GetComponent<Light>();
}
private void Update()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_008d: Unknown result type (might be due to invalid IL or missing references)
_elapsed += Time.deltaTime;
float num = Mathf.Clamp01(_elapsed / Mathf.Max(0.01f, Seconds));
((Component)this).transform.localScale = _startScale * Mathf.Lerp(1f, 2.6f, num);
if ((Object)(object)_renderer != (Object)null)
{
Color color = _renderer.material.color;
color.a = 1f - num;
_renderer.material.color = color;
}
if ((Object)(object)_light != (Object)null)
{
_light.intensity = Mathf.Lerp(30f, 0f, num);
}
if (num >= 1f)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
}
[BepInPlugin("com.hatsuneexo.htfhollowpurple", "HTF Hollow Purple", "3.2.0")]
[BepInProcess("How to Fish.exe")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "com.hatsuneexo.htfhollowpurple";
internal static ManualLogSource Log;
internal static ConfigEntry<Key> FireKey;
internal static ConfigEntry<float> ChargeTime;
internal static ConfigEntry<float> Cooldown;
internal static ConfigEntry<float> Range;
internal static ConfigEntry<float> Radius;
internal static ConfigEntry<float> BeamSeconds;
internal static ConfigEntry<string> BeamColor;
internal static ConfigEntry<bool> KillBosses;
internal static ConfigEntry<bool> UseGameExplosionEffects;
internal static ConfigEntry<string> SoundFile;
internal static ConfigEntry<float> SoundVolume;
internal static ConfigEntry<string> RequiredItem;
internal static ConfigEntry<int> Damage;
internal static ConfigEntry<float> Knockback;
internal static ConfigEntry<float> OrbSpeed;
internal static ConfigEntry<bool> PoseHands;
internal static AudioClip Clip;
private float _lastFired = -99f;
private bool _busy;
private void Awake()
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Expected O, but got Unknown
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Expected O, but got Unknown
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Expected O, but got Unknown
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
//IL_014e: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: Expected O, but got Unknown
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Expected O, but got Unknown
//IL_024c: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: Expected O, but got Unknown
//IL_0289: Unknown result type (might be due to invalid IL or missing references)
//IL_0293: Expected O, but got Unknown
//IL_030a: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Expected O, but got Unknown
//IL_0323: Unknown result type (might be due to invalid IL or missing references)
//IL_034e: Unknown result type (might be due to invalid IL or missing references)
Log = ((BaseUnityPlugin)this).Logger;
FireKey = ((BaseUnityPlugin)this).Config.Bind<Key>("General", "FireKey", (Key)22, "Tecla que carga y dispara. Por defecto H: V la usa el micrófono del juego.");
ChargeTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ChargeTime", 1.1f, new ConfigDescription("Segundos de carga antes del disparo. Es el momento en que las dos esferas se juntan.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
Cooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Cooldown", 8f, new ConfigDescription("Segundos entre disparos.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
Range = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Range", 120f, new ConfigDescription("Alcance del rayo, en metros.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 500f), Array.Empty<object>()));
Radius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Radius", 6f, new ConfigDescription("Radio de aniquilación alrededor del rayo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>()));
BeamSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "BeamSeconds", 1.4f, new ConfigDescription("Cuánto permanece el rayo en pantalla tras dispararse.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 6f), Array.Empty<object>()));
BeamColor = ((BaseUnityPlugin)this).Config.Bind<string>("Visual", "BeamColor", "9B30FF", "Color del rayo en hexadecimal RRGGBB.");
UseGameExplosionEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "UseGameExplosionEffects", true, "Dispara además los efectos de explosión del propio juego a lo largo del rayo. Es lo que le da el impacto de verdad; apágalo si te satura la pantalla.");
KillBosses = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "KillBosses", true, "Si también aniquila a los jefes. Ojo: matar al jefe de un botón afecta a la partida de todos, no solo a la tuya.");
RequiredItem = ((BaseUnityPlugin)this).Config.Bind<string>("Balance", "RequiredItem", "", "Nombre del objeto que hay que llevar en la mano para poder disparar. Vacío = sin requisito. Al disparar, el log te dice qué llevas, para que sepas qué nombre poner aquí.");
Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Balance", "Damage", 99999, new ConfigDescription("Daño por golpe. Enorme a propósito: es una aniquilación, no un arma.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 999999), Array.Empty<object>()));
Knockback = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "Knockback", 40f, new ConfigDescription("Fuerza con la que salen despedidos los cuerpos.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 300f), Array.Empty<object>()));
OrbSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("General", "OrbSpeed", 45f, new ConfigDescription("Velocidad a la que avanza el orbe, en metros por segundo. Más lento se ve mejor; más rápido se siente más contundente.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>()));
PoseHands = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "PoseHands", true, "Extiende las manos hacia delante durante la carga, usando la cinemática inversa del propio juego. No es la pose exacta del anime, pero deja de disparar de brazos caídos.");
SoundFile = ((BaseUnityPlugin)this).Config.Bind<string>("Audio", "SoundFile", "hollow-purple", "Nombre del archivo de sonido, sin extensión. Se busca en la carpeta Sounds/ de cualquier plugin instalado, así que vale tanto la de este mod como la de HTFSoundAPI.");
SoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "SoundVolume", 0.8f, new ConfigDescription("Volumen del sonido del disparo.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
Net.EnsureSerializers();
new Harmony("com.hatsuneexo.htfhollowpurple").PatchAll(Assembly.GetExecutingAssembly());
((MonoBehaviour)this).StartCoroutine(LoadSound());
Log.LogInfo((object)$"Listo. Pulsa {FireKey.Value} para el purple.");
}
private IEnumerator LoadSound()
{
yield return null;
string text = Sounds.Find(SoundFile.Value);
if (text == null)
{
Log.LogInfo((object)("Sin sonido: pon '" + SoundFile.Value + ".mp3' en la carpeta Sounds/ del mod."));
yield break;
}
yield return AudioLoading.Load(text, stream: false, delegate(AudioClip clip)
{
Clip = clip;
Log.LogInfo((object)$"Sonido cargado: {((Object)clip).name} ({clip.length:0.0}s)");
}, delegate(string msg)
{
Log.LogWarning((object)msg);
});
}
private void Update()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
Net.Tick();
if (_busy || (int)FireKey.Value == 0)
{
return;
}
Keyboard current = Keyboard.current;
if (current == null)
{
return;
}
KeyControl val = current[FireKey.Value];
if (val == null || !((ButtonControl)val).wasPressedThisFrame)
{
return;
}
if (Time.time - _lastFired < Cooldown.Value)
{
float num = Cooldown.Value - (Time.time - _lastFired);
Log.LogInfo((object)$"Todavía en enfriamiento: {num:0.0}s.");
return;
}
Camera camera = Aim.GetCamera();
if ((Object)(object)camera == (Object)null)
{
Log.LogWarning((object)"No encuentro la cámara; ¿estás dentro de una partida?");
return;
}
if (!Held.Allowed())
{
Log.LogInfo((object)("Necesitas llevar '" + RequiredItem.Value + "' en la mano."));
return;
}
_lastFired = Time.time;
((MonoBehaviour)this).StartCoroutine(Sequence(camera));
}
private IEnumerator Sequence(Camera camera)
{
_busy = true;
Color color = ParseColor(BeamColor.Value);
GameObject charge = Effects.SpawnCharge(((Component)camera).transform, color);
Hands.Extend(((Component)camera).transform);
if ((Object)(object)Clip != (Object)null)
{
AudioSource.PlayClipAtPoint(Clip, ((Component)camera).transform.position, SoundVolume.Value);
}
float elapsed = 0f;
while (elapsed < ChargeTime.Value)
{
elapsed += Time.deltaTime;
float t = elapsed / Mathf.Max(0.01f, ChargeTime.Value);
Effects.AnimateCharge(charge, t);
Hands.Push(t);
yield return null;
}
Effects.Destroy(charge);
Vector3 origin = ((Component)camera).transform.position + ((Component)camera).transform.forward * 1.2f;
Vector3 forward = ((Component)camera).transform.forward;
Effects.SpawnOrb(origin, forward, color, dealsDamage: true);
Net.Fire(origin, forward, Range.Value, Radius.Value);
yield return (object)new WaitForSecondsRealtime(0.35f);
Hands.Release();
yield return (object)new WaitForSeconds(Range.Value / Mathf.Max(1f, OrbSpeed.Value) + 0.6f);
_busy = false;
}
internal static Color ParseColor(string hex)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
Color result = default(Color);
if (ColorUtility.TryParseHtmlString("#" + hex.TrimStart(new char[1] { '#' }), ref result))
{
return result;
}
return new Color(0.61f, 0.19f, 1f);
}
}
internal static class Effects
{
private static Material _material;
private static Material GetMaterial(Color color)
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002c: Expected O, but got Unknown
//IL_006f: 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)
Material val = new Material(Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Sprites/Default"));
string[] array = new string[3] { "_BaseColor", "_Color", "_EmissionColor" };
foreach (string text in array)
{
if (val.HasProperty(text))
{
val.SetColor(text, color);
}
}
val.color = color;
if (val.HasProperty("_Surface"))
{
val.SetFloat("_Surface", 1f);
}
if (val.HasProperty("_Blend"))
{
val.SetFloat("_Blend", 1f);
}
if (val.HasProperty("_SrcBlend"))
{
val.SetFloat("_SrcBlend", 5f);
}
if (val.HasProperty("_DstBlend"))
{
val.SetFloat("_DstBlend", 1f);
}
if (val.HasProperty("_ZWrite"))
{
val.SetFloat("_ZWrite", 0f);
}
val.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
val.EnableKeyword("_EMISSION");
val.renderQueue = 3000;
return val;
}
private static GameObject Primitive(PrimitiveType type, Color color)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = GameObject.CreatePrimitive(type);
Collider component = obj.GetComponent<Collider>();
if ((Object)(object)component != (Object)null)
{
Object.Destroy((Object)(object)component);
}
Renderer component2 = obj.GetComponent<Renderer>();
if ((Object)(object)component2 != (Object)null)
{
component2.material = GetMaterial(color);
}
return obj;
}
internal static GameObject SpawnCharge(Transform camera, Color color)
{
//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)
//IL_0017: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: 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_0097: Expected O, but got Unknown
GameObject val = new GameObject("HollowPurpleCharge");
val.transform.SetParent(camera, false);
val.transform.localPosition = new Vector3(0f, -0.18f, 1.1f);
BuildSphere(val.transform, new Color(1f, 0.16f, 0.22f));
BuildSphere(val.transform, new Color(0.24f, 0.45f, 1f));
Light obj = val.AddComponent<Light>();
obj.color = color;
obj.range = 10f;
obj.intensity = 0f;
return val;
}
private static void BuildSphere(Transform parent, Color color)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: 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)
//IL_0058: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Primitive((PrimitiveType)0, color);
val.transform.SetParent(parent, false);
GameObject obj = Primitive((PrimitiveType)0, new Color(color.r, color.g, color.b, 0.35f));
obj.transform.SetParent(val.transform, false);
obj.transform.localScale = Vector3.one * 1.9f;
}
internal static void AnimateCharge(GameObject charge, float t)
{
//IL_006b: 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_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: 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)
if (!((Object)(object)charge == (Object)null))
{
t = Mathf.Clamp01(t);
float num = Mathf.Lerp(0.55f, 0.02f, t * t);
float num2 = Mathf.Lerp(0.1f, 0.3f, t);
float num3 = t * 900f;
Transform transform = charge.transform;
if (transform.childCount >= 2)
{
Vector3 val = new Vector3(Mathf.Cos(num3 * ((float)Math.PI / 180f)), Mathf.Sin(num3 * ((float)Math.PI / 180f)), 0f) * num;
transform.GetChild(0).localPosition = val;
transform.GetChild(1).localPosition = -val;
transform.GetChild(0).localScale = Vector3.one * num2;
transform.GetChild(1).localScale = Vector3.one * num2;
}
Light component = charge.GetComponent<Light>();
if ((Object)(object)component != (Object)null)
{
component.intensity = Mathf.Lerp(0f, 14f, t * t);
}
}
}
internal static void SpawnOrb(Vector3 origin, Vector3 direction, Color color, bool dealsDamage)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: 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_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Primitive((PrimitiveType)0, color);
((Object)val).name = "HollowPurpleOrb";
val.transform.position = origin;
val.transform.localScale = Vector3.one * Plugin.Radius.Value;
TrailRenderer obj = val.AddComponent<TrailRenderer>();
obj.time = 0.6f;
obj.startWidth = Plugin.Radius.Value * 1.6f;
obj.endWidth = 0f;
((Renderer)obj).material = GetMaterial(color);
obj.numCapVertices = 6;
GameObject obj2 = Primitive((PrimitiveType)0, new Color(color.r, color.g, color.b, 0.28f));
obj2.transform.SetParent(val.transform, false);
obj2.transform.localScale = Vector3.one * 2.1f;
Orb orb = val.AddComponent<Orb>();
orb.Direction = direction;
orb.Speed = Plugin.OrbSpeed.Value;
orb.Range = Plugin.Range.Value;
orb.Radius = Plugin.Radius.Value;
orb.DealsDamage = dealsDamage;
}
internal static void SpawnBeam(Vector3 origin, Vector3 direction, float range, float radius, Color color, float seconds)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: 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)
GameObject obj = Primitive((PrimitiveType)2, color);
((Object)obj).name = "HollowPurpleBeam";
obj.transform.position = origin + direction * (range * 0.5f);
obj.transform.rotation = Quaternion.LookRotation(direction) * Quaternion.Euler(90f, 0f, 0f);
obj.transform.localScale = new Vector3(radius * 0.5f, range * 0.5f, radius * 0.5f);
Light obj2 = obj.AddComponent<Light>();
obj2.color = color;
obj2.range = radius * 6f;
obj2.intensity = 12f;
obj.AddComponent<BeamFade>().Seconds = seconds;
}
internal static void Destroy(GameObject go)
{
if ((Object)(object)go != (Object)null)
{
Object.Destroy((Object)(object)go);
}
}
}
internal class BeamFade : MonoBehaviour
{
internal float Seconds = 1.4f;
private float _elapsed;
private Vector3 _startScale;
private Renderer _renderer;
private Light _light;
private void Start()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
_startScale = ((Component)this).transform.localScale;
_renderer = ((Component)this).GetComponent<Renderer>();
_light = ((Component)this).GetComponent<Light>();
}
private void Update()
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
_elapsed += Time.deltaTime;
float num = Mathf.Clamp01(_elapsed / Mathf.Max(0.01f, Seconds));
float num2 = Mathf.Lerp(1f, 2.2f, num);
((Component)this).transform.localScale = new Vector3(_startScale.x * num2, _startScale.y, _startScale.z * num2);
if ((Object)(object)_renderer != (Object)null)
{
Color color = _renderer.material.color;
color.a = 1f - num;
_renderer.material.color = color;
}
if ((Object)(object)_light != (Object)null)
{
_light.intensity = Mathf.Lerp(12f, 0f, num);
}
if (num >= 1f)
{
Object.Destroy((Object)(object)((Component)this).gameObject);
}
}
}
internal static class Annihilate
{
private static bool _resolved;
private static Type _creature;
private static Type _creatureManager;
private static FieldInfo _aliveCreatures;
private static FieldInfo _managerInstance;
private static FieldInfo _localPlayer;
private static MethodInfo _localHit;
private static void Resolve()
{
if (!_resolved)
{
_resolved = true;
_creature = AccessTools.TypeByName("Creature");
_creatureManager = AccessTools.TypeByName("CreatureManager");
Type type = AccessTools.TypeByName("Player");
if (_creature != null)
{
_localHit = AccessTools.Method(_creature, "LocalHit", (Type[])null, (Type[])null);
}
if (_creatureManager != null)
{
_aliveCreatures = AccessTools.Field(_creatureManager, "_aliveCreatures");
_managerInstance = AccessTools.Field(_creatureManager, "_instance");
}
if (type != null)
{
_localPlayer = AccessTools.Field(type, "LocalPlayer");
}
if (_localHit == null)
{
Plugin.Log.LogWarning((object)"No encuentro Creature.LocalHit: el orbe no hará daño.");
}
}
}
private static object InstanceOf(Type type, FieldInfo field)
{
object obj = field?.GetValue(null);
if (obj != null)
{
return obj;
}
if (!(type == null))
{
return Object.FindObjectOfType(type);
}
return null;
}
internal static void At(Vector3 center, float radius, Vector3 direction, HashSet<object> already)
{
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
Resolve();
if (_localHit == null || _aliveCreatures == null)
{
return;
}
object obj = InstanceOf(_creatureManager, _managerInstance);
if (obj == null || !(_aliveCreatures.GetValue(obj) is IEnumerable source))
{
return;
}
object player = _localPlayer?.GetValue(null);
float num = radius * radius;
foreach (object item in source.Cast<object>().ToList())
{
if (item == null || already.Contains(item))
{
continue;
}
Component val = (Component)((item is Component) ? item : null);
if (val != null && !((Object)(object)val == (Object)null))
{
Vector3 position = val.transform.position;
Vector3 val2 = position - center;
if (!(((Vector3)(ref val2)).sqrMagnitude > num) && (Plugin.KillBosses.Value || !IsBoss(item)))
{
already.Add(item);
Hit(item, val, position, direction, player);
}
}
}
}
private static void Hit(object creature, Component component, Vector3 position, Vector3 direction, object player)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
try
{
_localHit.Invoke(creature, new object[8]
{
component.transform,
position,
direction,
player,
Plugin.Damage.Value,
true,
direction * Plugin.Knockback.Value,
false
});
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("No pude golpear: " + (ex.InnerException?.Message ?? ex.Message)));
}
}
private static bool IsBoss(object creature)
{
PropertyInfo propertyInfo = AccessTools.Property(creature.GetType(), "IsBoss");
if (propertyInfo == null)
{
return false;
}
try
{
return (bool)propertyInfo.GetValue(creature);
}
catch
{
return false;
}
}
}
}