Decompiled source of YujiCursedEnergy v0.3.1

YujiMod.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using MelonLoader;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.XR;
using UnityEngine.XR;
using YujiMod;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "Yuji Cursed Energy", "0.3.0", "YourName", null)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("YujiMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("YujiMod")]
[assembly: AssemblyTitle("YujiMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace YujiMod
{
	public class Core : MelonMod
	{
		private class Hand
		{
			public bool right;

			public Transform tf;

			public ButtonControl trigger;

			public ButtonControl grip;

			public ButtonControl secondary;

			public ButtonControl stick;

			public bool warnedNoDevice;

			public bool dTrig;

			public bool dGrip;

			public bool dSec;

			public bool dStk;

			public bool xTrig;

			public bool xGrip;

			public bool xSec;

			public bool xStk;

			public bool xrValid;

			public bool xrSeen;

			public float nextControlTry;

			public bool hasPose;

			public Vector3 lastPos;

			public Vector3 vel;

			public bool fist;

			public float glowStart;

			public float glow;

			public bool glowShown;

			public bool glowScanned;

			public Transform glowRoot;

			public List<GlowMat> glowMats = new List<GlowMat>();

			public GameObject lightGo;

			public Light light;

			public float nextPunch;

			public bool prevCombo;

			public Color glowColor = new Color(0.25f, 0.55f, 1f);
		}

		private class GlowMat
		{
			public Material m;

			public bool hasEmission;

			public bool emissionKw;

			public Color origEmission;

			public string baseProp;

			public Color origBase;
		}

		private class Pending
		{
			public Rigidbody rb;

			public Vector3 dir;

			public float time;
		}

		private class Imbued
		{
			public Rigidbody rb;

			public string name;

			public bool sharp;

			public float until;

			public Vector3 lastPos;

			public Vector3 dir = Vector3.forward;

			public float speed;

			public bool hasPos;

			public List<GlowMat> mats = new List<GlowMat>();

			public List<Collider> cols = new List<Collider>();
		}

		private class Burst
		{
			public GameObject go;

			public float age;

			public float size;
		}

		private const float GlowRise = 8f;

		private const float GlowFall = 4f;

		private const float GlowIntensity = 4f;

		private const float LightIntensity = 3f;

		private const float GlowLightRange = 1.2f;

		private const float PunchMinSpeed = 1.5f;

		private const float PunchRadius = 0.14f;

		private const float PunchForward = 0.1f;

		private const float PunchCooldown = 0.5f;

		private const float PunchBase = 2.5f;

		private const float DivergentDelay = 0.4f;

		private const float DivergentForce = 14f;

		private const float DivergentRadius = 0.6f;

		private const float BlackFlashMin = 0f;

		private const float BlackFlashMax = 1.5f;

		private const float BlackFlashForce = 35f;

		private const float BlackFlashRadius = 0.9f;

		private const float SeriesWindow = 4f;

		private const float ImbueDuration = 20f;

		private const float ImbueReach = 0.25f;

		private const float WeaponMinSpeed = 2f;

		private const float WeaponHitCooldown = 0.4f;

		private const float WeaponBoost = 6f;

		private const float WeaponFlashChance = 0.2f;

		private const float SharpCutChance = 0.3f;

		private const float BurstTime = 0.25f;

		private static readonly Quaternion AimOffset = Quaternion.Euler(0f, 0f, 0f);

		private static readonly Color Blood = new Color(0.8f, 0.02f, 0.05f);

		private static readonly Color CursedBlue = new Color(0.25f, 0.55f, 1f);

		private static readonly Color SeriesColor = new Color(0.9f, 0.1f, 0.15f);

		private Hand[] hands;

		private bool xrBroken;

		private bool kbF;

		private bool kbG;

		private static readonly BindingFlags BF = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy;

		private Type hvrManagerType;

		private object hvrManager;

		private bool hvrBroken;

		private bool hvrTypeWarned;

		private bool hvrDumped;

		private bool hvrCtrlDumped;

		private int hvrFails;

		private float nextHvrTry;

		private float nextAlive;

		private int xrFails;

		private float nextScan;

		private int scans;

		private readonly List<Pending> pending = new List<Pending>();

		private readonly List<Imbued> imbued = new List<Imbued>();

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

		private float seriesUntil;

		private readonly List<Burst> bursts = new List<Burst>();

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

		private readonly HashSet<int> hitSet = new HashSet<int>();

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

		private readonly Dictionary<string, float> skipUntil = new Dictionary<string, float>();

		private Material bloodMat;

		private Shader unlitShader;

		public override void OnInitializeMelon()
		{
			hands = new Hand[2]
			{
				new Hand
				{
					right = false
				},
				new Hand
				{
					right = true
				}
			};
			((MelonBase)this).LoggerInstance.Msg("Yuji mod loaded");
		}

		public override void OnUpdate()
		{
			if (hands == null)
			{
				return;
			}
			if (Time.time >= nextAlive)
			{
				nextAlive = Time.time + 30f;
				((MelonBase)this).LoggerInstance.Msg("[alive] handsL=" + ((Object)(object)hands[0].tf != (Object)null) + " handsR=" + ((Object)(object)hands[1].tf != (Object)null) + " hvr=" + (hvrManager != null));
			}
			Safe("keyboard", ReadKeyboard);
			Safe("hvr", UpdateHvr);
			Hand[] array = hands;
			foreach (Hand hand in array)
			{
				Hand hh = hand;
				Safe(hand.right ? "handR" : "handL", delegate
				{
					UpdateHand(hh);
				});
			}
			Safe("pending", UpdatePending);
			Safe("imbued", UpdateImbued);
			Safe("bursts", UpdateBursts);
		}

		private void Safe(string part, Action a)
		{
			if (skipUntil.TryGetValue(part, out var value) && Time.time < value)
			{
				return;
			}
			try
			{
				a();
			}
			catch (Exception ex)
			{
				errCount.TryGetValue(part, out var value2);
				value2 = (errCount[part] = value2 + 1);
				if (value2 <= 3)
				{
					((MelonBase)this).LoggerInstance.Error("[error] " + part + " #" + value2 + ": " + ex);
				}
				skipUntil[part] = Time.time + 1f;
			}
		}

		private void ScanHands()
		{
			nextScan = Time.time + 3f;
			scans++;
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return;
			}
			Transform root = ((Component)main).transform.root;
			Transform val = null;
			Transform val2 = null;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			foreach (Transform item in Object.FindObjectsOfType<Transform>())
			{
				string text = ((Object)item).name.ToLowerInvariant();
				bool flag = text.Contains("left");
				bool flag2 = text.Contains("right");
				if (flag == flag2)
				{
					continue;
				}
				int num4 = Score(text);
				if (num4 <= 0)
				{
					continue;
				}
				bool flag3 = (Object)(object)item.root == (Object)(object)root;
				if (scans <= 3 && num3 < 25)
				{
					num3++;
					((MelonBase)this).LoggerInstance.Msg("hand candidate: " + PathOf(item) + " score=" + num4 + (flag3 ? " [rig]" : ""));
				}
				if (flag3)
				{
					if (flag && num4 > num)
					{
						num = num4;
						val = item;
					}
					if (flag2 && num4 > num2)
					{
						num2 = num4;
						val2 = item;
					}
				}
			}
			hands[0].tf = val;
			hands[1].tf = val2;
			if ((Object)(object)val != (Object)null)
			{
				((MelonBase)this).LoggerInstance.Msg("left hand = " + PathOf(val));
			}
			if ((Object)(object)val2 != (Object)null)
			{
				((MelonBase)this).LoggerInstance.Msg("right hand = " + PathOf(val2));
			}
		}

		private static int Score(string n)
		{
			string[] array = new string[10] { "finger", "thumb", "pinky", "bone", "joint", "interactor", "poke", "teleport", "canvas", "ray" };
			foreach (string value in array)
			{
				if (n.Contains(value))
				{
					return 0;
				}
			}
			if (n.Contains("controller"))
			{
				return 3;
			}
			if (n.Contains("hand"))
			{
				return 2;
			}
			return 0;
		}

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

		private void EnsureControls(Hand h)
		{
			if (h.trigger != null || Time.time < h.nextControlTry)
			{
				return;
			}
			h.nextControlTry = Time.time + 2f;
			string text = (h.right ? "RightHand" : "LeftHand");
			XRController val = (h.right ? XRController.rightHand : XRController.leftHand);
			if (val == null)
			{
				if (!h.warnedNoDevice)
				{
					h.warnedNoDevice = true;
					((MelonBase)this).LoggerInstance.Warning(text + ": XRController not found in Input System");
				}
				return;
			}
			h.trigger = GetButton((InputControl)(object)val, "triggerButton", "triggerPressed");
			h.grip = GetButton((InputControl)(object)val, "gripButton", "gripPressed");
			h.secondary = GetButton((InputControl)(object)val, "secondaryButton");
			h.stick = GetButton((InputControl)(object)val, "primary2DAxisClick", "thumbstickClicked");
			((MelonBase)this).LoggerInstance.Msg(text + ": IS device layout=" + ((InputControl)val).layout + " enabled=" + ((InputDevice)val).enabled + " runInBackground=" + ((InputDevice)val).canRunInBackground);
			((MelonBase)this).LoggerInstance.Msg(text + ": controls found (trigger=" + (h.trigger != null) + ", grip=" + (h.grip != null) + ", B/Y=" + (h.secondary != null) + ", stick=" + (h.stick != null) + ")");
		}

		private static ButtonControl GetButton(InputControl dev, params string[] names)
		{
			foreach (string text in names)
			{
				InputControl val = dev.TryGetChildControl(text);
				ButtonControl val2 = ((val == null) ? null : ((Il2CppObjectBase)val).TryCast<ButtonControl>());
				if (val2 != null)
				{
					return val2;
				}
			}
			return null;
		}

		private object GetMember(object obj, Type type, string name)
		{
			try
			{
				if (type == null)
				{
					return null;
				}
				PropertyInfo property = type.GetProperty(name, BF);
				if (property != null)
				{
					MethodInfo getMethod = property.GetGetMethod();
					if (getMethod == null || (obj == null && !getMethod.IsStatic))
					{
						return null;
					}
					return property.GetValue(getMethod.IsStatic ? null : obj, null);
				}
				FieldInfo field = type.GetField(name, BF);
				if (field != null)
				{
					if (obj == null && !field.IsStatic)
					{
						return null;
					}
					return field.GetValue(field.IsStatic ? null : obj);
				}
			}
			catch (Exception)
			{
			}
			return null;
		}

		private Type FindHvrType(string simpleName)
		{
			try
			{
				Assembly.Load("Il2CppHurricaneVR.Framework");
			}
			catch (Exception)
			{
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				if (!assembly.GetName().Name.Contains("HurricaneVR"))
				{
					continue;
				}
				try
				{
					Type[] types = assembly.GetTypes();
					foreach (Type type in types)
					{
						if (type.Name == simpleName)
						{
							return type;
						}
					}
				}
				catch (Exception)
				{
				}
			}
			return null;
		}

		private void HvrFail(Exception e)
		{
			hvrFails++;
			if (hvrFails >= 10)
			{
				hvrBroken = true;
				((MelonBase)this).LoggerInstance.Warning("[hvr] disabled: " + e.GetType().Name + " " + e.Message);
			}
		}

		private void UpdateHvr()
		{
			if (hvrBroken || Time.time < nextHvrTry)
			{
				return;
			}
			nextHvrTry = Time.time + 2f;
			try
			{
				if (hvrManagerType == null)
				{
					hvrManagerType = FindHvrType("HVRInputManager");
					if (hvrManagerType == null)
					{
						if (!hvrTypeWarned)
						{
							hvrTypeWarned = true;
							((MelonBase)this).LoggerInstance.Warning("[hvr] HVRInputManager type not found");
						}
						return;
					}
					((MelonBase)this).LoggerInstance.Msg("[hvr] type: " + hvrManagerType.FullName);
				}
				object member = GetMember(null, hvrManagerType, "Instance");
				if (member != null && hvrManager == null)
				{
					((MelonBase)this).LoggerInstance.Msg("[hvr] manager instance found");
				}
				hvrManager = member;
				if (member != null && !hvrDumped)
				{
					hvrDumped = true;
					DumpMembers(hvrManagerType);
				}
			}
			catch (Exception e)
			{
				HvrFail(e);
			}
		}

		private void ReadHvr(Hand h, out bool trig, out bool grip, out bool sec, out bool stk)
		{
			trig = (grip = (sec = (stk = false)));
			if (hvrBroken || hvrManager == null)
			{
				return;
			}
			try
			{
				object member = GetMember(hvrManager, hvrManagerType, h.right ? "RightController" : "LeftController");
				if (member != null)
				{
					if (!hvrCtrlDumped)
					{
						hvrCtrlDumped = true;
						DumpMembers(member.GetType());
					}
					trig = HvrActive(member, "TriggerButtonState", "TriggerButton");
					grip = HvrActive(member, "GripButtonState", "GripButton");
					sec = HvrActive(member, "SecondaryButtonState", "SecondaryButton");
					stk = HvrActive(member, "JoystickButtonState", "JoystickClicked", "JoystickButton");
					hvrFails = 0;
				}
			}
			catch (Exception e)
			{
				HvrFail(e);
			}
		}

		private bool HvrActive(object ctrl, params string[] names)
		{
			foreach (string name in names)
			{
				object member = GetMember(ctrl, ctrl.GetType(), name);
				if (member != null)
				{
					if (member is bool)
					{
						return (bool)member;
					}
					if (member is float num)
					{
						return num > 0.7f;
					}
					object member2 = GetMember(member, member.GetType(), "Active");
					if (member2 is bool)
					{
						return (bool)member2;
					}
					if (GetMember(member, member.GetType(), "Value") is float num2)
					{
						return num2 > 0.7f;
					}
					return false;
				}
			}
			return false;
		}

		private void DumpMembers(Type t)
		{
			string[] array = new string[9] { "button", "state", "trigger", "grip", "joystick", "primary", "secondary", "controller", "instance" };
			int num = 0;
			MemberInfo[] members = t.GetMembers(BF);
			foreach (MemberInfo memberInfo in members)
			{
				if (memberInfo.MemberType != MemberTypes.Property && memberInfo.MemberType != MemberTypes.Field)
				{
					continue;
				}
				string name = memberInfo.Name;
				if (name.StartsWith("Native"))
				{
					continue;
				}
				string text = name.ToLowerInvariant();
				bool flag = false;
				string[] array2 = array;
				foreach (string value in array2)
				{
					if (text.Contains(value))
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					((MelonBase)this).LoggerInstance.Msg("[hvr] " + t.Name + "." + name + " (" + memberInfo.MemberType.ToString() + ")");
					if (++num >= 60)
					{
						break;
					}
				}
			}
		}

		private void ReadKeyboard()
		{
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				kbF = (kbG = false);
				return;
			}
			kbF = ((ButtonControl)current.fKey).isPressed;
			kbG = ((ButtonControl)current.gKey).isPressed;
		}

		private void LogEdge(Hand h, string name, bool now, ref bool prev, string src)
		{
			if (now != prev)
			{
				prev = now;
				((MelonBase)this).LoggerInstance.Msg("[input] " + (h.right ? "Right " : "Left ") + name + (now ? (" DOWN (" + src + ")") : " up"));
			}
		}

		private void ReadXr(Hand h)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (xrBroken)
			{
				h.xTrig = (h.xGrip = (h.xSec = (h.xStk = false)));
				return;
			}
			try
			{
				InputDevice deviceAtXRNode = InputDevices.GetDeviceAtXRNode((XRNode)(h.right ? 5 : 4));
				h.xrValid = ((InputDevice)(ref deviceAtXRNode)).isValid;
				if (!h.xrValid)
				{
					h.xTrig = (h.xGrip = (h.xSec = (h.xStk = false)));
					return;
				}
				if (!h.xrSeen)
				{
					h.xrSeen = true;
					((MelonBase)this).LoggerInstance.Msg("[xr] " + (h.right ? "Right" : "Left") + ": " + ((InputDevice)(ref deviceAtXRNode)).name);
				}
				bool flag = default(bool);
				h.xTrig = ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.triggerButton, ref flag) && flag;
				bool flag2 = default(bool);
				h.xGrip = ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.gripButton, ref flag2) && flag2;
				bool flag3 = default(bool);
				h.xSec = ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.secondaryButton, ref flag3) && flag3;
				bool flag4 = default(bool);
				h.xStk = ((InputDevice)(ref deviceAtXRNode)).TryGetFeatureValue(CommonUsages.primary2DAxisClick, ref flag4) && flag4;
				xrFails = 0;
			}
			catch (Exception ex)
			{
				h.xTrig = (h.xGrip = (h.xSec = (h.xStk = false)));
				xrFails++;
				if (xrFails >= 10)
				{
					xrBroken = true;
					((MelonBase)this).LoggerInstance.Warning("XR fallback input disabled: " + ex.GetType().Name);
				}
			}
		}

		private static bool Pressed(ButtonControl c)
		{
			if (c != null)
			{
				return c.isPressed;
			}
			return false;
		}

		private void UpdateHand(Hand h)
		{
			//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_0049: 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_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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0076: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_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_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)h.tf == (Object)null)
			{
				if (Time.time >= nextScan)
				{
					ScanHands();
				}
				if ((Object)(object)h.tf == (Object)null)
				{
					return;
				}
			}
			EnsureControls(h);
			Vector3 position = h.tf.position;
			Quaternion rot = h.tf.rotation * AimOffset;
			if (h.hasPose && Time.deltaTime > 0f)
			{
				h.vel = Vector3.Lerp(h.vel, (position - h.lastPos) / Time.deltaTime, 0.5f);
			}
			h.lastPos = position;
			h.hasPose = true;
			bool flag = Pressed(h.trigger);
			bool flag2 = Pressed(h.grip);
			bool flag3 = Pressed(h.secondary);
			bool flag4 = Pressed(h.stick);
			ReadXr(h);
			ReadHvr(h, out var trig, out var grip, out var sec, out var stk);
			bool flag5 = trig || flag || h.xTrig;
			bool flag6 = grip || flag2 || h.xGrip;
			bool flag7 = sec || flag3 || h.xSec;
			bool now = stk || flag4 || h.xStk;
			LogEdge(h, "trigger", flag5, ref h.dTrig, trig ? "HVR" : (flag ? "IS" : "XR"));
			LogEdge(h, "grip", flag6, ref h.dGrip, grip ? "HVR" : (flag2 ? "IS" : "XR"));
			LogEdge(h, "B/Y", flag7, ref h.dSec, sec ? "HVR" : (flag3 ? "IS" : "XR"));
			LogEdge(h, "stick", now, ref h.dStk, stk ? "HVR" : (flag4 ? "IS" : "XR"));
			bool flag8 = (flag6 && flag5) || (h.right && kbF);
			bool flag9 = (flag7 && !flag5) || (h.right && kbG);
			if (flag8 && !h.fist)
			{
				h.glowStart = Time.time;
				((MelonBase)this).LoggerInstance.Msg("[glow] " + (h.right ? "Right" : "Left") + " ON");
			}
			h.fist = flag8;
			UpdateGlow(h, position);
			UpdatePunch(h, position, rot);
			if (flag9 && !h.prevCombo)
			{
				TryImbue(h, position, rot);
			}
			h.prevCombo = flag9;
		}

		private void UpdateGlow(Hand h, Vector3 pos)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Time.time < seriesUntil;
			bool flag2 = h.fist || flag;
			h.glowColor = (flag ? SeriesColor : CursedBlue);
			float num = (flag2 ? 1f : 0f);
			h.glow = Mathf.MoveTowards(h.glow, num, (flag2 ? 8f : 4f) * Time.deltaTime);
			if (flag2)
			{
				EnsureGlowTargets(h);
			}
			bool flag3 = h.glow > 0.001f;
			if (flag3 || h.glowShown)
			{
				float num2 = (flag3 ? (0.9f + 0.1f * Mathf.Sin(Time.time * 25f)) : 1f);
				ApplyGlow(h, h.glow * num2);
				h.glowShown = flag3;
			}
			if ((Object)(object)h.lightGo == (Object)null && flag3)
			{
				CreateHandLight(h);
			}
			if ((Object)(object)h.lightGo != (Object)null)
			{
				((Behaviour)h.light).enabled = flag3;
				if (flag3)
				{
					h.lightGo.transform.position = pos;
					h.light.color = h.glowColor;
					h.light.intensity = 3f * h.glow;
				}
			}
		}

		private void CreateHandLight(Hand h)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			h.lightGo = new GameObject("CursedLight");
			Object.DontDestroyOnLoad((Object)(object)h.lightGo);
			h.light = h.lightGo.AddComponent<Light>();
			h.light.color = CursedBlue;
			h.light.range = 1.2f;
			h.light.intensity = 0f;
		}

		private void EnsureGlowTargets(Hand h)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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)
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return;
			}
			Transform root = ((Component)main).transform.root;
			if (h.glowScanned && (Object)(object)h.glowRoot == (Object)(object)root)
			{
				return;
			}
			h.glowScanned = true;
			h.glowRoot = root;
			h.glowMats.Clear();
			string text = (h.right ? "right" : "left");
			int num = 0;
			foreach (Renderer componentsInChild in ((Component)root).GetComponentsInChildren<Renderer>(true))
			{
				string text2 = PathOf(((Component)componentsInChild).transform).ToLowerInvariant();
				if (!text2.Contains(text) || !text2.Contains("hand") || text2.Contains("target") || text2.Contains("canvas"))
				{
					continue;
				}
				if (num++ >= 12)
				{
					break;
				}
				foreach (Material item in (Il2CppArrayBase<Material>)(object)componentsInChild.materials)
				{
					if (!((Object)(object)item == (Object)null))
					{
						GlowMat glowMat = new GlowMat
						{
							m = item
						};
						glowMat.hasEmission = item.HasProperty("_EmissionColor");
						if (glowMat.hasEmission)
						{
							glowMat.origEmission = item.GetColor("_EmissionColor");
							glowMat.emissionKw = item.IsKeywordEnabled("_EMISSION");
						}
						if (item.HasProperty("_BaseColor"))
						{
							glowMat.baseProp = "_BaseColor";
						}
						else if (item.HasProperty("_Color"))
						{
							glowMat.baseProp = "_Color";
						}
						if (glowMat.baseProp != null)
						{
							glowMat.origBase = item.GetColor(glowMat.baseProp);
						}
						h.glowMats.Add(glowMat);
					}
				}
			}
			((MelonBase)this).LoggerInstance.Msg("[glow] " + text + " hand renderers=" + num + " materials=" + h.glowMats.Count);
		}

		private void ApplyGlow(Hand h, float amount)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			ApplyGlowTo(h.glowMats, h.glowColor, amount);
		}

		private void ApplyGlowTo(List<GlowMat> mats, Color color, float amount)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			foreach (GlowMat mat in mats)
			{
				Material m = mat.m;
				if ((Object)(object)m == (Object)null)
				{
					continue;
				}
				if (mat.hasEmission)
				{
					if (amount > 0.01f)
					{
						m.EnableKeyword("_EMISSION");
						m.SetColor("_EmissionColor", color * (4f * amount));
					}
					else
					{
						m.SetColor("_EmissionColor", mat.origEmission);
						if (!mat.emissionKw)
						{
							m.DisableKeyword("_EMISSION");
						}
					}
				}
				if (mat.baseProp != null)
				{
					m.SetColor(mat.baseProp, Color.Lerp(mat.origBase, color, 0.55f * Mathf.Clamp01(amount)));
				}
			}
		}

		private void UpdatePunch(Hand h, Vector3 pos, Quaternion rot)
		{
			//IL_003c: 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_0047: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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)
			//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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			bool flag = Time.time < seriesUntil;
			if (!(h.fist || flag) || Time.time < h.nextPunch)
			{
				return;
			}
			float magnitude = ((Vector3)(ref h.vel)).magnitude;
			if (magnitude < 1.5f)
			{
				return;
			}
			Vector3 dir = h.vel / magnitude;
			Vector3 val = pos + rot * Vector3.forward * 0.1f;
			Rigidbody val2 = null;
			float num = float.MaxValue;
			Vector3 point = val;
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(val, 0.14f))
			{
				Rigidbody attachedRigidbody = item.attachedRigidbody;
				if (!((Object)(object)attachedRigidbody == (Object)null) && IsEnemy(attachedRigidbody) && (!punchCd.TryGetValue(((Object)attachedRigidbody).GetInstanceID(), out var value) || !(Time.time < value)))
				{
					Vector3 val3 = attachedRigidbody.worldCenterOfMass - val;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						val2 = attachedRigidbody;
						Bounds bounds = item.bounds;
						point = ((Bounds)(ref bounds)).ClosestPoint(val);
					}
				}
			}
			if (!((Object)(object)val2 == (Object)null))
			{
				if (punchCd.Count > 200)
				{
					punchCd.Clear();
				}
				punchCd[((Object)val2).GetInstanceID()] = Time.time + 0.5f;
				h.nextPunch = Time.time + 0.5f;
				float num2 = Time.time - h.glowStart;
				bool flag2 = h.fist && num2 >= 0f && num2 <= 1.5f;
				bool flag3 = flag || flag2;
				if (flag3)
				{
					BlackFlash(point, dir);
					seriesUntil = Time.time + 4f;
				}
				else
				{
					DivergentFist(val2, point, dir);
				}
				((MelonBase)this).LoggerInstance.Msg("[punch] " + ((!flag3) ? "divergent" : (flag ? "BLACK FLASH (series)" : "BLACK FLASH")) + " glowAge=" + num2.ToString("0.00") + "s speed=" + magnitude.ToString("0.0") + " on " + ((Object)val2).name);
			}
		}

		private void DivergentFist(Rigidbody rb, Vector3 point, Vector3 dir)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			rb.AddForceAtPosition(dir * 2.5f, point, (ForceMode)2);
			SpawnBurst(point, 0.3f, MakeMat(CursedBlue));
			pending.Add(new Pending
			{
				rb = rb,
				dir = dir,
				time = Time.time + 0.4f
			});
		}

		private void UpdatePending()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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)
			for (int num = this.pending.Count - 1; num >= 0; num--)
			{
				Pending pending = this.pending[num];
				if ((Object)(object)pending.rb == (Object)null)
				{
					this.pending.RemoveAt(num);
				}
				else if (!(Time.time < pending.time))
				{
					this.pending.RemoveAt(num);
					Vector3 worldCenterOfMass = pending.rb.worldCenterOfMass;
					Impact(worldCenterOfMass, pending.dir, 14f, 0.6f);
					SpawnBurst(worldCenterOfMass, 0.84000003f, MakeMat(CursedBlue));
					((MelonBase)this).LoggerInstance.Msg("[divergent] second impact on " + ((Object)pending.rb).name);
				}
			}
		}

		private void BlackFlash(Vector3 point, Vector3 dir)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			Impact(point, dir + Vector3.up * 0.15f, 35f, 0.9f);
			SpawnBurst(point, 1.1f, MakeMat(new Color(0.9f, 0.05f, 0.05f)));
			SpawnBurst(point, 0.6f, MakeMat(Color.black));
			SpawnLightning(point, dir);
		}

		private void Impact(Vector3 center, Vector3 dir, float force, float radius)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			hitSet.Clear();
			Vector3 normalized = ((Vector3)(ref dir)).normalized;
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(center, radius))
			{
				Rigidbody attachedRigidbody = item.attachedRigidbody;
				if (!((Object)(object)attachedRigidbody == (Object)null) && IsEnemy(attachedRigidbody) && hitSet.Add(((Object)attachedRigidbody).GetInstanceID()))
				{
					Vector3 val = attachedRigidbody.worldCenterOfMass - center;
					float magnitude = ((Vector3)(ref val)).magnitude;
					float num = 1f - 0.5f * Mathf.Clamp01(magnitude / radius);
					attachedRigidbody.AddForce(normalized * force * num, (ForceMode)2);
				}
			}
		}

		private void SpawnLightning(Vector3 origin, Vector3 dir)
		{
			//IL_0010: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_003e: 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_0047: 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_0070: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00a1: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			Material mat = MakeMat(new Color(0.9f, 0.05f, 0.05f));
			Material mat2 = MakeMat(Color.black);
			for (int i = 0; i < 5; i++)
			{
				Vector3 val = dir + Random.insideUnitSphere * 1.2f;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				float num = Random.Range(0.8f, 1.6f);
				Vector3[] array = (Vector3[])(object)new Vector3[9];
				for (int j = 0; j <= 8; j++)
				{
					array[j] = origin + normalized * (num * (float)j / 8f);
					if (j > 0)
					{
						ref Vector3 reference = ref array[j];
						reference += Random.insideUnitSphere * 0.1f;
					}
				}
				MakeBolt(array, mat, 0.08f);
				MakeBolt(array, mat2, 0.03f);
			}
		}

		private void MakeBolt(Vector3[] pts, Material mat, float width)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Bolt");
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.positionCount = pts.Length;
			val2.startWidth = width;
			val2.endWidth = width * 0.3f;
			if ((Object)(object)mat != (Object)null)
			{
				((Renderer)val2).material = mat;
			}
			for (int i = 0; i < pts.Length; i++)
			{
				val2.SetPosition(i, pts[i]);
			}
			Object.Destroy((Object)(object)val, 0.3f);
		}

		private void TryImbue(Hand h, Vector3 pos, Quaternion rot)
		{
			//IL_0015: 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_0017: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_007f: 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_0088: 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_008e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			string text = (h.right ? "Right" : "Left");
			Vector3 val = pos + rot * Vector3.forward * 0.1f;
			Rigidbody val2 = null;
			Rigidbody val3 = null;
			float num = float.MaxValue;
			float num2 = float.MaxValue;
			foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(val, 0.25f))
			{
				Rigidbody attachedRigidbody = item.attachedRigidbody;
				if (!((Object)(object)attachedRigidbody == (Object)null) && IsEnemy(attachedRigidbody))
				{
					Bounds bounds = item.bounds;
					Vector3 val4 = ((Bounds)(ref bounds)).ClosestPoint(val) - val;
					float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
					if (sqrMagnitude < num2)
					{
						num2 = sqrMagnitude;
						val3 = attachedRigidbody;
					}
					if (sqrMagnitude < num && IsGrabbableObject(attachedRigidbody))
					{
						num = sqrMagnitude;
						val2 = attachedRigidbody;
					}
				}
			}
			bool flag = false;
			if ((Object)(object)val2 == (Object)null && (Object)(object)val3 != (Object)null)
			{
				val2 = val3;
				flag = true;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				((MelonBase)this).LoggerInstance.Msg("[imbue] " + text + ": no weapon in reach");
				return;
			}
			Imbued imbued = null;
			foreach (Imbued item2 in this.imbued)
			{
				if ((Object)(object)item2.rb == (Object)(object)val2)
				{
					imbued = item2;
					break;
				}
			}
			if (imbued == null)
			{
				imbued = new Imbued
				{
					rb = val2,
					name = ((Object)val2).name,
					sharp = IsSharp(val2)
				};
				foreach (Renderer componentsInChild in ((Component)val2).GetComponentsInChildren<Renderer>(true))
				{
					if (imbued.mats.Count >= 20)
					{
						break;
					}
					AddMaterials(componentsInChild, imbued.mats);
				}
				foreach (Collider componentsInChild2 in ((Component)val2).GetComponentsInChildren<Collider>(true))
				{
					imbued.cols.Add(componentsInChild2);
				}
				this.imbued.Add(imbued);
			}
			imbued.until = Time.time + 20f;
			((MelonBase)this).LoggerInstance.Msg("[imbue] " + text + ": " + imbued.name + (imbued.sharp ? " (sharp)" : " (blunt)") + " for " + 20f + "s materials=" + imbued.mats.Count + " colliders=" + imbued.cols.Count + (flag ? " [fallback]" : ""));
		}

		private bool IsGrabbableObject(Rigidbody rb)
		{
			foreach (Component component in ((Component)rb).GetComponents<Component>())
			{
				if (!((Object)(object)component == (Object)null))
				{
					string text = ((Object)component).ToString();
					if (text != null && text.Contains("Grabbable"))
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool IsSharp(Rigidbody rb)
		{
			string text = (((Object)rb).name + " " + ((Object)((Component)rb).transform.root).name).ToLowerInvariant();
			string[] array = new string[25]
			{
				"knife", "sword", "katana", "blade", "axe", "machete", "saw", "dagger", "cleaver", "scythe",
				"scalpel", "spear", "kunai", "sickle", "razor", "shiv", "cutter", "hatchet", "sabre", "saber",
				"cutlass", "bayonet", "shank", "glaive", "halberd"
			};
			foreach (string value in array)
			{
				if (text.Contains(value))
				{
					return true;
				}
			}
			return false;
		}

		private void AddMaterials(Renderer r, List<GlowMat> list)
		{
			//IL_0051: 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_00ae: 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)
			foreach (Material item in (Il2CppArrayBase<Material>)(object)r.materials)
			{
				if (!((Object)(object)item == (Object)null))
				{
					GlowMat glowMat = new GlowMat
					{
						m = item
					};
					glowMat.hasEmission = item.HasProperty("_EmissionColor");
					if (glowMat.hasEmission)
					{
						glowMat.origEmission = item.GetColor("_EmissionColor");
						glowMat.emissionKw = item.IsKeywordEnabled("_EMISSION");
					}
					if (item.HasProperty("_BaseColor"))
					{
						glowMat.baseProp = "_BaseColor";
					}
					else if (item.HasProperty("_Color"))
					{
						glowMat.baseProp = "_Color";
					}
					if (glowMat.baseProp != null)
					{
						glowMat.origBase = item.GetColor(glowMat.baseProp);
					}
					list.Add(glowMat);
				}
			}
		}

		private void UpdateImbued()
		{
			//IL_009a: 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_00d1: 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_0133: 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_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)
			//IL_00ed: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			for (int num = this.imbued.Count - 1; num >= 0; num--)
			{
				Imbued imbued = this.imbued[num];
				if ((Object)(object)imbued.rb == (Object)null)
				{
					this.imbued.RemoveAt(num);
				}
				else if (Time.time >= imbued.until)
				{
					ApplyGlowTo(imbued.mats, CursedBlue, 0f);
					((MelonBase)this).LoggerInstance.Msg("[imbue] " + imbued.name + " expired");
					this.imbued.RemoveAt(num);
				}
				else
				{
					ApplyGlowTo(imbued.mats, CursedBlue, 0.8f * (0.9f + 0.1f * Mathf.Sin(Time.time * 20f)));
					Vector3 worldCenterOfMass = imbued.rb.worldCenterOfMass;
					if (imbued.hasPos && Time.deltaTime > 0f)
					{
						Vector3 val = worldCenterOfMass - imbued.lastPos;
						imbued.speed = Mathf.Lerp(imbued.speed, ((Vector3)(ref val)).magnitude / Time.deltaTime, 0.5f);
						if (((Vector3)(ref val)).sqrMagnitude > 1E-08f)
						{
							imbued.dir = ((Vector3)(ref val)).normalized;
						}
					}
					imbued.lastPos = worldCenterOfMass;
					imbued.hasPos = true;
					if (!(imbued.speed < 2f))
					{
						if (weaponCd.Count > 200)
						{
							weaponCd.Clear();
						}
						int num2 = 0;
						foreach (Collider col in imbued.cols)
						{
							if ((Object)(object)col == (Object)null)
							{
								continue;
							}
							Bounds bounds = col.bounds;
							foreach (Collider item in (Il2CppArrayBase<Collider>)(object)Physics.OverlapBox(((Bounds)(ref bounds)).center, ((Bounds)(ref bounds)).extents + Vector3.one * 0.03f, Quaternion.identity))
							{
								Rigidbody attachedRigidbody = item.attachedRigidbody;
								if ((Object)(object)attachedRigidbody == (Object)null || (Object)(object)attachedRigidbody == (Object)(object)imbued.rb || !IsEnemy(attachedRigidbody))
								{
									continue;
								}
								int instanceID = ((Object)attachedRigidbody).GetInstanceID();
								if (!weaponCd.TryGetValue(instanceID, out var value) || !(Time.time < value))
								{
									weaponCd[instanceID] = Time.time + 0.4f;
									Bounds bounds2 = item.bounds;
									OnWeaponHit(imbued, attachedRigidbody, ((Bounds)(ref bounds2)).ClosestPoint(((Bounds)(ref bounds)).center));
									if (++num2 >= 3)
									{
										break;
									}
								}
							}
							if (num2 >= 3)
							{
								break;
							}
						}
					}
				}
			}
		}

		private void OnWeaponHit(Imbued w, Rigidbody target, Vector3 point)
		{
			//IL_0002: 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)
			//IL_0011: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			target.AddForceAtPosition(w.dir * 6f, point, (ForceMode)2);
			SpawnBurst(point, 0.25f, MakeMat(CursedBlue));
			string text = "boost";
			if (w.sharp)
			{
				if (Random.value < 0.3f)
				{
					text = "cut(" + SeverJoints(target) + ")";
				}
			}
			else if (Random.value < 0.2f)
			{
				BlackFlash(point, w.dir);
				text = "BLACK FLASH";
			}
			((MelonBase)this).LoggerInstance.Msg("[weapon] " + w.name + (w.sharp ? " (sharp)" : " (blunt)") + " -> " + text + " on " + ((Object)target).name + " speed=" + w.speed.ToString("0.0"));
		}

		private int SeverJoints(Rigidbody rb)
		{
			int num = 0;
			foreach (Joint component in ((Component)rb).GetComponents<Joint>())
			{
				if (!((Object)(object)component == (Object)null) && (!((Object)(object)((Il2CppObjectBase)component).TryCast<CharacterJoint>() == (Object)null) || !((Object)(object)((Il2CppObjectBase)component).TryCast<ConfigurableJoint>() == (Object)null)))
				{
					Object.Destroy((Object)(object)component);
					num++;
				}
			}
			return num;
		}

		private void SpawnBurst(Vector3 p, float size, Material custom = null)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)0);
			((Object)val).name = "Burst";
			val.transform.position = p;
			val.transform.localScale = Vector3.one * 0.1f;
			Object.Destroy((Object)(object)val.GetComponent<Collider>());
			Material val2 = (((Object)(object)custom != (Object)null) ? custom : GetBloodMat());
			if ((Object)(object)val2 != (Object)null)
			{
				val.GetComponent<Renderer>().material = val2;
			}
			bursts.Add(new Burst
			{
				go = val,
				size = size
			});
		}

		private void UpdateBursts()
		{
			//IL_0087: 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)
			for (int num = bursts.Count - 1; num >= 0; num--)
			{
				Burst burst = bursts[num];
				if ((Object)(object)burst.go == (Object)null)
				{
					bursts.RemoveAt(num);
				}
				else
				{
					burst.age += Time.deltaTime;
					float num2 = burst.age / 0.25f;
					if (num2 >= 1f)
					{
						Object.Destroy((Object)(object)burst.go);
						bursts.RemoveAt(num);
					}
					else
					{
						burst.go.transform.localScale = Vector3.one * Mathf.Lerp(0.1f, burst.size, num2);
					}
				}
			}
		}

		private bool IsEnemy(Rigidbody rb)
		{
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null && (Object)(object)((Component)rb).transform.root == (Object)(object)((Component)main).transform.root)
			{
				return false;
			}
			return true;
		}

		private Material GetBloodMat()
		{
			//IL_007c: 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)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if ((Object)(object)bloodMat != (Object)null)
			{
				return bloodMat;
			}
			Shader val = Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				((MelonBase)this).LoggerInstance.Warning("Shader not found, effects will be invisible");
				return null;
			}
			unlitShader = val;
			bloodMat = new Material(val)
			{
				color = Blood
			};
			((MelonBase)this).LoggerInstance.Msg("blood shader: " + ((Object)val).name);
			return bloodMat;
		}

		private Material MakeMat(Color c)
		{
			//IL_001d: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			GetBloodMat();
			if ((Object)(object)unlitShader == (Object)null)
			{
				return null;
			}
			return new Material(unlitShader)
			{
				color = c
			};
		}
	}
}