Decompiled source of TrainingMode v1.1.6

TrainingMode.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FistVR;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("TrainingMode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TrainingMode")]
[assembly: AssemblyTitle("TrainingMode")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TrainingMode;

public enum DrillType
{
	None,
	BabyPanda,
	BillDrill,
	Mozambique,
	ElPresidente,
	BoxDrill,
	Invent60
}
public enum SegmentColor
{
	Yellow,
	White,
	Red
}
public class SegmentDefinition
{
	public readonly SosigBodyPart BodyPart;

	public readonly SegmentColor StartColor;

	public readonly int StartCount;

	public SegmentDefinition(SosigBodyPart part, SegmentColor color, int count)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		BodyPart = part;
		StartColor = color;
		StartCount = count;
	}
}
public class DrillDefinition
{
	public DrillType DrillType;

	public List<SegmentDefinition> Segments;

	public bool HasLockout;

	public int LockoutAfterHits;

	public int UnlockBodyHitsRequired;

	public int UnlockHeadHitsRequired;

	public int UnlockAnyHitsRequired;

	public float UnlockTimeoutSeconds;
}
public static class DrillLibrary
{
	public static string GetDisplayName(DrillType type)
	{
		return type switch
		{
			DrillType.BabyPanda => "Baby Panda", 
			DrillType.BillDrill => "Bill Drill", 
			DrillType.Mozambique => "Mozambique", 
			DrillType.ElPresidente => "El Presidente", 
			DrillType.BoxDrill => "Box Drill", 
			DrillType.Invent60 => "Invent60", 
			_ => "", 
		};
	}

	public static DrillDefinition GetDefinition(DrillType type)
	{
		return type switch
		{
			DrillType.BabyPanda => new DrillDefinition
			{
				DrillType = DrillType.BabyPanda,
				Segments = new List<SegmentDefinition>
				{
					new SegmentDefinition((SosigBodyPart)0, SegmentColor.Yellow, 2)
				},
				HasLockout = false
			}, 
			DrillType.BillDrill => new DrillDefinition
			{
				DrillType = DrillType.BillDrill,
				Segments = new List<SegmentDefinition>
				{
					new SegmentDefinition((SosigBodyPart)1, SegmentColor.Yellow, 6)
				},
				HasLockout = false
			}, 
			DrillType.Mozambique => new DrillDefinition
			{
				DrillType = DrillType.Mozambique,
				Segments = new List<SegmentDefinition>
				{
					new SegmentDefinition((SosigBodyPart)1, SegmentColor.Yellow, 2),
					new SegmentDefinition((SosigBodyPart)0, SegmentColor.White, 1)
				},
				HasLockout = false
			}, 
			DrillType.ElPresidente => new DrillDefinition
			{
				DrillType = DrillType.ElPresidente,
				Segments = new List<SegmentDefinition>
				{
					new SegmentDefinition((SosigBodyPart)1, SegmentColor.Red, 4)
				},
				HasLockout = true,
				LockoutAfterHits = 2,
				UnlockBodyHitsRequired = 0,
				UnlockHeadHitsRequired = 0,
				UnlockAnyHitsRequired = 4,
				UnlockTimeoutSeconds = 6f
			}, 
			DrillType.BoxDrill => new DrillDefinition
			{
				DrillType = DrillType.BoxDrill,
				Segments = new List<SegmentDefinition>
				{
					new SegmentDefinition((SosigBodyPart)1, SegmentColor.Red, 2),
					new SegmentDefinition((SosigBodyPart)0, SegmentColor.White, 1)
				},
				HasLockout = true,
				LockoutAfterHits = 2,
				UnlockBodyHitsRequired = 2,
				UnlockHeadHitsRequired = 1,
				UnlockTimeoutSeconds = 6f
			}, 
			DrillType.Invent60 => new DrillDefinition
			{
				DrillType = DrillType.Invent60,
				Segments = new List<SegmentDefinition>
				{
					new SegmentDefinition((SosigBodyPart)3, SegmentColor.Yellow, 2),
					new SegmentDefinition((SosigBodyPart)0, SegmentColor.White, 2)
				},
				HasLockout = false
			}, 
			_ => null, 
		};
	}
}
public class DrillManager : MonoBehaviour
{
	private struct WeightEntry
	{
		public DrillType Type;

		public float CumWeight;
	}

	public static DrillManager Instance;

	public bool TrainingModeActive;

	public bool BabyPandaEnabled = true;

	public bool BillDrillEnabled = true;

	public bool MozambiqueEnabled = true;

	public bool ElPresidenteEnabled = true;

	public bool BoxDrillEnabled = true;

	public bool Invent60Enabled = true;

	private readonly List<SosigDrillComponent> _allActive = new List<SosigDrillComponent>();

	private readonly List<Sosig> _pendingKills = new List<Sosig>();

	private readonly List<WeightEntry> _weightedDrills = new List<WeightEntry>();

	private static readonly Dictionary<DrillType, int> BaseWeights = new Dictionary<DrillType, int>
	{
		{
			DrillType.BabyPanda,
			19
		},
		{
			DrillType.BillDrill,
			8
		},
		{
			DrillType.Mozambique,
			43
		},
		{
			DrillType.ElPresidente,
			10
		},
		{
			DrillType.BoxDrill,
			10
		},
		{
			DrillType.Invent60,
			10
		}
	};

	public int PhysicsFrame { get; private set; }

	internal List<SosigDrillComponent> AllActive => _allActive;

	private void Awake()
	{
		Instance = this;
		RecalculateWeights();
	}

	private void FixedUpdate()
	{
		PhysicsFrame++;
	}

	private void Update()
	{
		if (_pendingKills.Count == 0)
		{
			return;
		}
		for (int i = 0; i < _pendingKills.Count; i++)
		{
			Sosig val = _pendingKills[i];
			if ((Object)(object)val != (Object)null)
			{
				val.KillSosig();
			}
		}
		_pendingKills.Clear();
	}

	public void ScheduleKill(Sosig sosig)
	{
		if ((Object)(object)sosig != (Object)null && !_pendingKills.Contains(sosig))
		{
			_pendingKills.Add(sosig);
		}
	}

	public void RecalculateWeights()
	{
		_weightedDrills.Clear();
		List<DrillType> list = new List<DrillType>();
		List<int> list2 = new List<int>();
		if (BabyPandaEnabled)
		{
			list.Add(DrillType.BabyPanda);
			list2.Add(BaseWeights[DrillType.BabyPanda]);
		}
		if (BillDrillEnabled)
		{
			list.Add(DrillType.BillDrill);
			list2.Add(BaseWeights[DrillType.BillDrill]);
		}
		if (MozambiqueEnabled)
		{
			list.Add(DrillType.Mozambique);
			list2.Add(BaseWeights[DrillType.Mozambique]);
		}
		if (ElPresidenteEnabled)
		{
			list.Add(DrillType.ElPresidente);
			list2.Add(BaseWeights[DrillType.ElPresidente]);
		}
		if (BoxDrillEnabled)
		{
			list.Add(DrillType.BoxDrill);
			list2.Add(BaseWeights[DrillType.BoxDrill]);
		}
		if (Invent60Enabled)
		{
			list.Add(DrillType.Invent60);
			list2.Add(BaseWeights[DrillType.Invent60]);
		}
		if (list.Count == 0)
		{
			return;
		}
		float num = 0f;
		foreach (int item in list2)
		{
			num += (float)item;
		}
		float num2 = 0f;
		for (int i = 0; i < list.Count; i++)
		{
			num2 += (float)list2[i] / num;
			_weightedDrills.Add(new WeightEntry
			{
				Type = list[i],
				CumWeight = num2
			});
		}
	}

	public void AssignDrill(SosigDrillComponent component)
	{
		if (_weightedDrills.Count == 0)
		{
			return;
		}
		float value = Random.value;
		DrillType type = _weightedDrills[_weightedDrills.Count - 1].Type;
		foreach (WeightEntry weightedDrill in _weightedDrills)
		{
			if (value <= weightedDrill.CumWeight)
			{
				type = weightedDrill.Type;
				break;
			}
		}
		component.InitializeDrill(type);
	}

	public void OnTrainingModeToggled(bool newState)
	{
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Invalid comparison between Unknown and I4
		TrainingModeActive = newState;
		if (!newState)
		{
			foreach (SosigDrillComponent item in new List<SosigDrillComponent>(_allActive))
			{
				if ((Object)(object)item != (Object)null)
				{
					item.ClearDrill();
				}
			}
			_allActive.Clear();
			return;
		}
		Sosig[] array = Object.FindObjectsOfType<Sosig>();
		foreach (Sosig val in array)
		{
			if (!((Object)(object)val == (Object)null) && (int)val.BodyState != 3)
			{
				SosigDrillComponent component = ((Component)val).GetComponent<SosigDrillComponent>();
				if ((Object)(object)component != (Object)null)
				{
					component.ClearDrill();
					AssignDrill(component);
				}
				else
				{
					component = ((Component)val).gameObject.AddComponent<SosigDrillComponent>();
					AssignDrill(component);
				}
			}
		}
	}

	public void RegisterComponent(SosigDrillComponent component)
	{
		if (!_allActive.Contains(component))
		{
			_allActive.Add(component);
		}
	}

	public void UnregisterComponent(SosigDrillComponent component)
	{
		_allActive.Remove(component);
	}

	public void ReportValidBodyHit()
	{
		for (int num = _allActive.Count - 1; num >= 0; num--)
		{
			SosigDrillComponent sosigDrillComponent = _allActive[num];
			if ((Object)(object)sosigDrillComponent != (Object)null && sosigDrillComponent.IsLocked)
			{
				sosigDrillComponent.OnGlobalValidBodyHit();
			}
		}
	}

	public void ReportValidHeadHit()
	{
		for (int num = _allActive.Count - 1; num >= 0; num--)
		{
			SosigDrillComponent sosigDrillComponent = _allActive[num];
			if ((Object)(object)sosigDrillComponent != (Object)null && sosigDrillComponent.IsLocked)
			{
				sosigDrillComponent.OnGlobalValidHeadHit();
			}
		}
	}

	public void ReportAnyValidHit()
	{
		for (int num = _allActive.Count - 1; num >= 0; num--)
		{
			SosigDrillComponent sosigDrillComponent = _allActive[num];
			if ((Object)(object)sosigDrillComponent != (Object)null && sosigDrillComponent.IsLocked)
			{
				sosigDrillComponent.OnGlobalAnyValidHit();
			}
		}
	}
}
public class KillBillExplosion : MonoBehaviour
{
	private float _radius;

	internal static readonly Color KillBillBlue = new Color(0f, 0.5f, 1f);

	public static void Spawn(Vector3 worldPos, float radius)
	{
		//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_0010: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("TM_KillBillExplosion");
		val.transform.position = worldPos;
		val.AddComponent<KillBillExplosion>()._radius = radius;
	}

	private void Start()
	{
		//IL_0006: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		KillBillRing.Spawn(((Component)this).transform.position, _radius);
		StunShockwave.Spawn(((Component)this).transform.position, KillBillBlue, _radius * 0.5f);
		if ((Object)(object)DrillManager.Instance != (Object)null)
		{
			List<SosigDrillComponent> allActive = DrillManager.Instance.AllActive;
			for (int num = allActive.Count - 1; num >= 0; num--)
			{
				SosigDrillComponent sosigDrillComponent = allActive[num];
				if (!((Object)(object)sosigDrillComponent == (Object)null) && Vector3.Distance(((Component)this).transform.position, ((Component)sosigDrillComponent).transform.position) <= _radius)
				{
					sosigDrillComponent.TriggerKillBillStun();
				}
			}
		}
		Object.Destroy((Object)(object)((Component)this).gameObject);
	}
}
internal class KillBillRing : MonoBehaviour
{
	private LineRenderer _lr;

	private float _maxRadius;

	private float _elapsed;

	private const float Duration = 1.2f;

	private const int Segments = 64;

	internal static void Spawn(Vector3 worldPos, float maxRadius)
	{
		//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_0010: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("TM_KillBillRing");
		val.transform.position = worldPos;
		val.AddComponent<KillBillRing>()._maxRadius = maxRadius;
	}

	private void Start()
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Expected O, but got Unknown
		_lr = ((Component)this).gameObject.AddComponent<LineRenderer>();
		_lr.useWorldSpace = true;
		_lr.loop = true;
		_lr.positionCount = 64;
		_lr.startWidth = 0.12f;
		_lr.endWidth = 0.12f;
		_lr.numCapVertices = 4;
		Shader val = Shader.Find("Particles/Alpha Blended") ?? Shader.Find("Sprites/Default");
		if ((Object)(object)val != (Object)null)
		{
			((Renderer)_lr).material = new Material(val);
		}
		SetColor(1f);
	}

	private void Update()
	{
		//IL_006f: 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)
		_elapsed += Time.unscaledDeltaTime;
		float num = _elapsed / 1.2f;
		if (num >= 1f)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		float num2 = _maxRadius * num;
		SetColor(1f - num);
		for (int i = 0; i < 64; i++)
		{
			float num3 = (float)i / 64f * (float)Math.PI * 2f;
			_lr.SetPosition(i, ((Component)this).transform.position + new Vector3(Mathf.Cos(num3) * num2, 0f, Mathf.Sin(num3) * num2));
		}
	}

	private void SetColor(float alpha)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		Color killBillBlue = KillBillExplosion.KillBillBlue;
		Color val = default(Color);
		((Color)(ref val))..ctor(killBillBlue.r, killBillBlue.g, killBillBlue.b, alpha);
		_lr.startColor = val;
		_lr.endColor = val;
	}
}
[BepInPlugin("h3vr.invent60.trainingmode", "TrainingMode", "1.1.6")]
public class TrainingModePlugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigEntry<float> CfgKillBillRadius;

	private void Awake()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Expected O, but got Unknown
		//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)
		Log = ((BaseUnityPlugin)this).Logger;
		CfgKillBillRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Kill Bill", "Explosion radius meters", 8f, "Radius in which sosigs are stunned when a Bill Drill target is eliminated. (1 to 30)");
		GameObject val = new GameObject("TrainingModeDrillManager");
		DrillManager.Instance = val.AddComponent<DrillManager>();
		Object.DontDestroyOnLoad((Object)val);
		Harmony val2 = new Harmony("h3vr.invent60.trainingmode");
		val2.PatchAll(typeof(TrainingModePatches));
		val2.PatchAll(typeof(TrainingModeWristMenuPatch));
		Log.LogInfo((object)"[TrainingMode] v1.1.6 Loaded.");
	}
}
public class SegmentBillboard : MonoBehaviour
{
	private SosigLink _targetLink;

	private Text _numberText;

	private Text _shadowText;

	private Text _timerText;

	private float _totalTimeoutSeconds;

	private bool _ringActive;

	private bool _isLabel;

	private float _popTimer;

	private const float PopDuration = 0.18f;

	private const float PopPeakScale = 1.4f;

	private const float CanvasScale = 0.001f;

	private static Font _font;

	private static Font GetFont()
	{
		if ((Object)(object)_font == (Object)null)
		{
			_font = Font.CreateDynamicFontFromOSFont("Bahnschrift", 48);
		}
		return _font;
	}

	public static SegmentBillboard Create(SosigLink link, int startCount, SegmentColor startColor)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: 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_008d: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: 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_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("TM_Billboard", new Type[1] { typeof(RectTransform) });
		SetupCanvas(val);
		Text val2 = MakeText(val, "Shadow", 120, new Vector2(400f, 200f), new Vector2(6f, -6f), new Color(0f, 0f, 0f, 0.7f));
		val2.text = startCount.ToString();
		Text val3 = MakeText(val, "Number", 120, new Vector2(400f, 200f), Vector2.zero, GetColor(startColor));
		val3.text = startCount.ToString();
		GameObject val4 = new GameObject("Timer", new Type[1] { typeof(RectTransform) });
		val4.transform.SetParent(val.transform, false);
		RectTransform val5 = (RectTransform)val4.transform;
		val5.sizeDelta = new Vector2(300f, 100f);
		val5.anchoredPosition = new Vector2(0f, -160f);
		Text val6 = val4.AddComponent<Text>();
		val6.font = GetFont();
		val6.fontSize = 50;
		val6.text = "6.0";
		val6.alignment = (TextAnchor)4;
		val6.horizontalOverflow = (HorizontalWrapMode)1;
		val6.verticalOverflow = (VerticalWrapMode)1;
		((Graphic)val6).color = new Color(1f, 0.6f, 0f);
		val4.SetActive(false);
		SegmentBillboard segmentBillboard = val.AddComponent<SegmentBillboard>();
		segmentBillboard._targetLink = link;
		segmentBillboard._numberText = val3;
		segmentBillboard._shadowText = val2;
		segmentBillboard._timerText = val6;
		segmentBillboard._isLabel = false;
		segmentBillboard.SnapToLink();
		return segmentBillboard;
	}

	public static SegmentBillboard CreateLabel(SosigLink link, string labelText)
	{
		//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)
		//IL_0023: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Expected O, but got Unknown
		//IL_006f: 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_0086: 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_00a4: Expected O, but got Unknown
		GameObject val = new GameObject("TM_DrillLabel", new Type[1] { typeof(RectTransform) });
		SetupCanvas(val);
		Text val2 = MakeText(val, "Shadow", 45, new Vector2(800f, 120f), new Vector2(3f, -3f), new Color(0f, 0f, 0f, 0.7f));
		val2.text = labelText;
		Text val3 = MakeText(val, "Label", 45, new Vector2(800f, 120f), Vector2.zero, new Color(0.9f, 0.9f, 0.9f));
		val3.text = labelText;
		SegmentBillboard segmentBillboard = val.AddComponent<SegmentBillboard>();
		segmentBillboard._targetLink = link;
		segmentBillboard._numberText = val3;
		segmentBillboard._shadowText = val2;
		segmentBillboard._isLabel = true;
		segmentBillboard.SnapToLink();
		return segmentBillboard;
	}

	private static void SetupCanvas(GameObject go)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		go.AddComponent<Canvas>().renderMode = (RenderMode)2;
		go.transform.localScale = new Vector3(0.001f, 0.001f, 0.001f);
	}

	private static Text MakeText(GameObject parent, string name, int fontSize, Vector2 size, Vector2 anchoredPos, Color color)
	{
		//IL_0014: 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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: 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_003d: 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)
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent.transform, false);
		RectTransform val2 = (RectTransform)val.transform;
		val2.sizeDelta = size;
		val2.anchoredPosition = anchoredPos;
		Text obj = val.AddComponent<Text>();
		obj.font = GetFont();
		obj.fontSize = fontSize;
		obj.alignment = (TextAnchor)4;
		obj.horizontalOverflow = (HorizontalWrapMode)1;
		obj.verticalOverflow = (VerticalWrapMode)1;
		((Graphic)obj).color = color;
		return obj;
	}

	private void SnapToLink()
	{
		//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_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)
		if (!((Object)(object)_targetLink == (Object)null))
		{
			((Component)this).transform.position = ((Component)_targetLink).transform.position + Vector3.up * (_isLabel ? 0.6f : 0.45f);
		}
	}

	private void LateUpdate()
	{
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_targetLink == (Object)null)
		{
			return;
		}
		try
		{
			FVRPlayerBody currentPlayerBody = GM.CurrentPlayerBody;
			if ((Object)(object)currentPlayerBody == (Object)null)
			{
				return;
			}
			Transform head = currentPlayerBody.Head;
			if ((Object)(object)head == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)_targetLink).transform.position;
			if (float.IsNaN(position.x) || float.IsNaN(position.y) || float.IsNaN(position.z))
			{
				return;
			}
			if (_isLabel)
			{
				((Component)this).transform.position = position + Vector3.up * 0.6f;
			}
			else
			{
				Vector3 val = position - head.position;
				float magnitude = ((Vector3)(ref val)).magnitude;
				Vector3 val2 = ((magnitude > 0.01f) ? (-val / magnitude) : Vector3.up);
				((Component)this).transform.position = position + val2 * 0.45f;
			}
			((Component)this).transform.LookAt(head.position);
			((Component)this).transform.Rotate(0f, 180f, 0f);
		}
		catch
		{
		}
		float num = 0.001f;
		if (_popTimer > 0f)
		{
			_popTimer -= Time.unscaledDeltaTime;
			float num2 = Mathf.Clamp01(_popTimer / 0.18f);
			num = 0.001f * Mathf.Lerp(1f, 1.4f, num2);
		}
		((Component)this).transform.localScale = new Vector3(num, num, num);
	}

	private void TriggerPop()
	{
		_popTimer = 0.18f;
	}

	public void UpdateCount(int count)
	{
		string text = ((count > 0) ? count.ToString() : "");
		if ((Object)(object)_numberText != (Object)null)
		{
			_numberText.text = text;
		}
		if ((Object)(object)_shadowText != (Object)null)
		{
			_shadowText.text = text;
		}
		if (count <= 0)
		{
			((Component)this).gameObject.SetActive(false);
		}
		else
		{
			TriggerPop();
		}
	}

	public void UpdateColor(SegmentColor color)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_numberText != (Object)null)
		{
			((Graphic)_numberText).color = GetColor(color);
		}
		TriggerPop();
	}

	public void SetLabelText(string text, Color color)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_numberText != (Object)null)
		{
			_numberText.text = text;
			((Graphic)_numberText).color = color;
		}
		if ((Object)(object)_shadowText != (Object)null)
		{
			_shadowText.text = text;
		}
		TriggerPop();
	}

	public void SetLabelTextQuiet(string text, Color color)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_numberText != (Object)null)
		{
			_numberText.text = text;
			((Graphic)_numberText).color = color;
		}
		if ((Object)(object)_shadowText != (Object)null)
		{
			_shadowText.text = text;
		}
	}

	public void ShowRing(float timeoutSeconds)
	{
		_ringActive = true;
		_totalTimeoutSeconds = timeoutSeconds;
		if ((Object)(object)_timerText != (Object)null)
		{
			_timerText.text = timeoutSeconds.ToString("F1");
			((Component)_timerText).gameObject.SetActive(true);
		}
		if (!((Component)this).gameObject.activeSelf)
		{
			((Component)this).gameObject.SetActive(true);
		}
	}

	public void HideRing()
	{
		_ringActive = false;
		if ((Object)(object)_timerText != (Object)null)
		{
			((Component)_timerText).gameObject.SetActive(false);
		}
	}

	public void UpdateRing(float fillAmount)
	{
		if (_ringActive && !((Object)(object)_timerText == (Object)null))
		{
			_timerText.text = (fillAmount * _totalTimeoutSeconds).ToString("F1");
		}
	}

	public void DestroySelf()
	{
		if ((Object)(object)this != (Object)null && (Object)(object)((Component)this).gameObject != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}

	private static Color GetColor(SegmentColor color)
	{
		//IL_0018: 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_0033: Unknown result type (might be due to invalid IL or missing references)
		return (Color)(color switch
		{
			SegmentColor.Yellow => new Color(1f, 44f / 51f, 0f), 
			SegmentColor.Red => new Color(44f / 51f, 10f / 51f, 10f / 51f), 
			_ => Color.white, 
		});
	}
}
public class SosigDrillComponent : MonoBehaviour
{
	private class ActiveSegment
	{
		public SegmentDefinition Definition;

		public SegmentColor CurrentColor;

		public int CurrentCount;

		public SosigLink TargetLink;

		public SegmentBillboard Billboard;

		public float LastHitTime = -99f;
	}

	private DrillDefinition _definition;

	private List<ActiveSegment> _segments;

	private bool _isLocked;

	private bool _lockoutUsed;

	private float _lockoutTimer;

	private int _globalBodyHitsReceived;

	private int _globalHeadHitsReceived;

	private int _globalAnyHitsReceived;

	private int _lockTriggerCount = -1;

	private SegmentBillboard _drillNameBillboard;

	private float _lockPulseTimer;

	private static readonly Color LockOrange = new Color(1f, 0.55f, 0f);

	private bool _isStunned;

	private float _stunTimer;

	private SosigOrder _priorSosigOrder;

	private float _regularStunPulseTimer;

	private bool _isKillBillStunned;

	private float _killBillStunTimer;

	private float _killBillPulseTimer;

	private float _glitchTimer;

	private float _torsoHit1Time = -99f;

	private float _torsoHit2Time = -99f;

	private float _torsoStunLastTime = -99f;

	private float _lowerHit1Time = -99f;

	private float _lowerHit2Time = -99f;

	private float _lowerStunLastTime = -99f;

	private const float StunDuration = 6f;

	private const float KillBillStunDuration = 3f;

	private const float StunBodyWindowSec = 2f;

	private const float PulseInterval = 0.5f;

	private const float GlitchInterval = 0.04f;

	private static readonly Color StunYellow = new Color(1f, 44f / 51f, 0f);

	private static readonly Color KillBillBlue = KillBillExplosion.KillBillBlue;

	private static readonly char[] GlitchChars = "abcdefghijklmnopqrstuvwxyz0123456789".ToCharArray();

	public bool IsLocked => _isLocked;

	public bool HasActiveDrill
	{
		get
		{
			if (_segments != null)
			{
				return _segments.Count > 0;
			}
			return false;
		}
	}

	public void InitializeDrill(DrillType type)
	{
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Invalid comparison between Unknown and I4
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		ClearDrill();
		_definition = DrillLibrary.GetDefinition(type);
		if (_definition == null)
		{
			return;
		}
		Sosig component = ((Component)this).GetComponent<Sosig>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		_segments = new List<ActiveSegment>();
		_isLocked = false;
		_lockoutUsed = false;
		_lockoutTimer = 0f;
		_globalBodyHitsReceived = 0;
		_globalHeadHitsReceived = 0;
		_globalAnyHitsReceived = 0;
		ResetStunTracking();
		foreach (SegmentDefinition segment in _definition.Segments)
		{
			SosigLink val = null;
			foreach (SosigLink link in component.Links)
			{
				if ((Object)(object)link != (Object)null && link.BodyPart == segment.BodyPart)
				{
					val = link;
					break;
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				SegmentBillboard billboard = SegmentBillboard.Create(val, segment.StartCount, segment.StartColor);
				_segments.Add(new ActiveSegment
				{
					Definition = segment,
					CurrentColor = segment.StartColor,
					CurrentCount = segment.StartCount,
					TargetLink = val,
					Billboard = billboard
				});
			}
		}
		if (_segments.Count < _definition.Segments.Count)
		{
			foreach (ActiveSegment segment2 in _segments)
			{
				segment2.Billboard?.DestroySelf();
			}
			_segments = null;
			return;
		}
		if (_definition.HasLockout)
		{
			foreach (ActiveSegment segment3 in _segments)
			{
				if ((int)segment3.Definition.BodyPart == 1)
				{
					_lockTriggerCount = segment3.Definition.StartCount - _definition.LockoutAfterHits;
					break;
				}
			}
		}
		SosigLink val2 = null;
		foreach (ActiveSegment segment4 in _segments)
		{
			if ((int)segment4.Definition.BodyPart == 0)
			{
				val2 = segment4.TargetLink;
				break;
			}
		}
		if ((Object)(object)val2 == (Object)null)
		{
			foreach (SosigLink link2 in component.Links)
			{
				if ((Object)(object)link2 != (Object)null && (int)link2.BodyPart == 0)
				{
					val2 = link2;
					break;
				}
			}
		}
		if ((Object)(object)val2 != (Object)null)
		{
			_drillNameBillboard = SegmentBillboard.CreateLabel(val2, DrillLibrary.GetDisplayName(type));
		}
		DrillManager.Instance.RegisterComponent(this);
	}

	public void OnLinkHit(SosigLink link)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Invalid comparison between Unknown and I4
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Invalid comparison between Unknown and I4
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Invalid comparison between Unknown and I4
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Invalid comparison between Unknown and I4
		if (_segments == null)
		{
			return;
		}
		float unscaledTime = Time.unscaledTime;
		if ((int)link.BodyPart == 1 && unscaledTime - _torsoStunLastTime >= 0.05f)
		{
			_torsoStunLastTime = unscaledTime;
			_torsoHit2Time = _torsoHit1Time;
			_torsoHit1Time = unscaledTime;
			if (_torsoHit2Time > 0f && unscaledTime - _torsoHit2Time <= 2f)
			{
				TriggerStun();
				_torsoHit1Time = -99f;
				_torsoHit2Time = -99f;
			}
		}
		if ((int)link.BodyPart == 3 && unscaledTime - _lowerStunLastTime >= 0.05f)
		{
			_lowerStunLastTime = unscaledTime;
			_lowerHit2Time = _lowerHit1Time;
			_lowerHit1Time = unscaledTime;
			if (_lowerHit2Time > 0f && unscaledTime - _lowerHit2Time <= 2f)
			{
				TriggerStun();
				_lowerHit1Time = -99f;
				_lowerHit2Time = -99f;
			}
		}
		if (_isLocked)
		{
			return;
		}
		ActiveSegment activeSegment = null;
		foreach (ActiveSegment segment in _segments)
		{
			if ((Object)(object)segment.TargetLink == (Object)(object)link)
			{
				activeSegment = segment;
				break;
			}
		}
		if (activeSegment != null && activeSegment.CurrentColor != SegmentColor.White && activeSegment.CurrentCount > 0 && !(unscaledTime - activeSegment.LastHitTime < 0.05f))
		{
			activeSegment.LastHitTime = unscaledTime;
			activeSegment.CurrentCount--;
			activeSegment.Billboard?.UpdateCount(activeSegment.CurrentCount);
			if ((int)activeSegment.Definition.BodyPart == 0)
			{
				TriggerStun();
			}
			DrillManager.Instance.ReportAnyValidHit();
			if ((int)activeSegment.Definition.BodyPart == 1)
			{
				DrillManager.Instance.ReportValidBodyHit();
			}
			else if ((int)activeSegment.Definition.BodyPart == 0)
			{
				DrillManager.Instance.ReportValidHeadHit();
			}
			if (_definition.HasLockout && !_lockoutUsed && _lockTriggerCount >= 0 && (int)activeSegment.Definition.BodyPart == 1 && activeSegment.CurrentCount == _lockTriggerCount)
			{
				TriggerLock(activeSegment);
			}
			else if (activeSegment.CurrentCount == 0)
			{
				OnSegmentCleared(activeSegment);
			}
		}
	}

	private void TriggerLock(ActiveSegment torsoSeg)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		_isLocked = true;
		_lockoutUsed = true;
		_lockoutTimer = _definition.UnlockTimeoutSeconds;
		_globalBodyHitsReceived = 0;
		_globalHeadHitsReceived = 0;
		_globalAnyHitsReceived = 0;
		_lockPulseTimer = 0f;
		if (torsoSeg.CurrentCount > 0)
		{
			torsoSeg.CurrentColor = SegmentColor.White;
			torsoSeg.Billboard?.UpdateColor(SegmentColor.White);
			torsoSeg.Billboard?.ShowRing(_definition.UnlockTimeoutSeconds);
			return;
		}
		foreach (ActiveSegment segment in _segments)
		{
			if ((int)segment.Definition.BodyPart == 0)
			{
				segment.Billboard?.ShowRing(_definition.UnlockTimeoutSeconds);
				break;
			}
		}
	}

	private void OnSegmentCleared(ActiveSegment clearedSeg)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Invalid comparison between Unknown and I4
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		if (_definition == null || _segments == null)
		{
			return;
		}
		if ((int)clearedSeg.Definition.BodyPart == 1 && _definition.DrillType != DrillType.BoxDrill)
		{
			foreach (ActiveSegment segment in _segments)
			{
				if ((int)segment.Definition.BodyPart == 0 && segment.CurrentColor == SegmentColor.White)
				{
					segment.CurrentColor = SegmentColor.Yellow;
					segment.Billboard?.UpdateColor(SegmentColor.Yellow);
				}
			}
		}
		if (_definition.DrillType == DrillType.Invent60 && (int)clearedSeg.Definition.BodyPart == 3)
		{
			TriggerStun();
			foreach (ActiveSegment segment2 in _segments)
			{
				if ((int)segment2.Definition.BodyPart == 0 && segment2.CurrentColor == SegmentColor.White)
				{
					segment2.CurrentColor = SegmentColor.Yellow;
					segment2.Billboard?.UpdateColor(SegmentColor.Yellow);
				}
			}
		}
		foreach (ActiveSegment segment3 in _segments)
		{
			if (segment3.CurrentCount > 0)
			{
				return;
			}
		}
		KillSosigFromDrill();
	}

	private void TriggerStun()
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		_stunTimer = 6f;
		if (_isStunned)
		{
			return;
		}
		_isStunned = true;
		_regularStunPulseTimer = 0.5f;
		if (_isKillBillStunned)
		{
			return;
		}
		Sosig component = ((Component)this).GetComponent<Sosig>();
		if ((Object)(object)component != (Object)null)
		{
			_priorSosigOrder = component.CurrentOrder;
			component.SetCurrentOrder((SosigOrder)0);
			if ((Object)(object)component.Agent != (Object)null)
			{
				component.Agent.isStopped = true;
			}
		}
		if ((Object)(object)_drillNameBillboard != (Object)null)
		{
			StunShockwave.Spawn(((Component)_drillNameBillboard).transform.position);
			_drillNameBillboard.SetLabelText("STUNNED", StunYellow);
		}
	}

	private void EndStun()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Invalid comparison between Unknown and I4
		//IL_0041: 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)
		if (!_isStunned)
		{
			return;
		}
		_isStunned = false;
		_stunTimer = 0f;
		if (_isKillBillStunned)
		{
			return;
		}
		Sosig component = ((Component)this).GetComponent<Sosig>();
		if ((Object)(object)component != (Object)null && (int)component.BodyState != 3)
		{
			component.SetCurrentOrder(_priorSosigOrder);
			if ((Object)(object)component.Agent != (Object)null)
			{
				component.Agent.isStopped = false;
			}
		}
		if ((Object)(object)_drillNameBillboard != (Object)null && _definition != null)
		{
			_drillNameBillboard.SetLabelText(DrillLibrary.GetDisplayName(_definition.DrillType), new Color(0.9f, 0.9f, 0.9f));
		}
	}

	public void TriggerKillBillStun()
	{
		//IL_008f: 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_0050: Unknown result type (might be due to invalid IL or missing references)
		_killBillStunTimer = 3f;
		if (_isKillBillStunned)
		{
			return;
		}
		_isKillBillStunned = true;
		_killBillPulseTimer = 0.3f;
		_glitchTimer = 0f;
		if (!_isStunned)
		{
			Sosig component = ((Component)this).GetComponent<Sosig>();
			if ((Object)(object)component != (Object)null)
			{
				_priorSosigOrder = component.CurrentOrder;
				component.SetCurrentOrder((SosigOrder)0);
				if ((Object)(object)component.Agent != (Object)null)
				{
					component.Agent.isStopped = true;
				}
			}
		}
		if ((Object)(object)_drillNameBillboard != (Object)null)
		{
			_drillNameBillboard.SetLabelTextQuiet(RandomGlitchString(), KillBillBlue);
		}
	}

	private void EndKillBillStun()
	{
		//IL_00c4: 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_003d: Invalid comparison between Unknown and I4
		//IL_0041: 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)
		if (!_isKillBillStunned)
		{
			return;
		}
		_isKillBillStunned = false;
		_killBillStunTimer = 0f;
		if (!_isStunned)
		{
			Sosig component = ((Component)this).GetComponent<Sosig>();
			if ((Object)(object)component != (Object)null && (int)component.BodyState != 3)
			{
				component.SetCurrentOrder(_priorSosigOrder);
				if ((Object)(object)component.Agent != (Object)null)
				{
					component.Agent.isStopped = false;
				}
			}
			if ((Object)(object)_drillNameBillboard != (Object)null && _definition != null)
			{
				_drillNameBillboard.SetLabelText(DrillLibrary.GetDisplayName(_definition.DrillType), new Color(0.9f, 0.9f, 0.9f));
			}
		}
		else if ((Object)(object)_drillNameBillboard != (Object)null)
		{
			_drillNameBillboard.SetLabelText("STUNNED", StunYellow);
		}
	}

	public void OnGlobalAnyValidHit()
	{
		if (_isLocked)
		{
			_globalAnyHitsReceived++;
			CheckUnlockCondition();
		}
	}

	public void OnGlobalValidBodyHit()
	{
		if (_isLocked)
		{
			_globalBodyHitsReceived++;
			CheckUnlockCondition();
		}
	}

	public void OnGlobalValidHeadHit()
	{
		if (_isLocked)
		{
			_globalHeadHitsReceived++;
			CheckUnlockCondition();
		}
	}

	private void CheckUnlockCondition()
	{
		if (_definition != null)
		{
			bool num = _definition.UnlockAnyHitsRequired <= 0 || _globalAnyHitsReceived >= _definition.UnlockAnyHitsRequired;
			bool flag = _definition.UnlockBodyHitsRequired <= 0 || _globalBodyHitsReceived >= _definition.UnlockBodyHitsRequired;
			bool flag2 = _definition.UnlockHeadHitsRequired <= 0 || _globalHeadHitsReceived >= _definition.UnlockHeadHitsRequired;
			if (num && flag && flag2)
			{
				Unlock();
			}
			else
			{
				UpdateRingProgress();
			}
		}
	}

	private void UpdateRingProgress()
	{
		if (_definition == null)
		{
			return;
		}
		float num = ((_definition.UnlockTimeoutSeconds > 0f) ? (_lockoutTimer / _definition.UnlockTimeoutSeconds) : 0f);
		float num2 = ((_definition.UnlockAnyHitsRequired > 0) ? ((float)_globalAnyHitsReceived / (float)_definition.UnlockAnyHitsRequired) : 1f);
		float num3 = ((_definition.UnlockBodyHitsRequired > 0) ? ((float)_globalBodyHitsReceived / (float)_definition.UnlockBodyHitsRequired) : 1f);
		float num4 = ((_definition.UnlockHeadHitsRequired > 0) ? ((float)_globalHeadHitsReceived / (float)_definition.UnlockHeadHitsRequired) : 1f);
		float num5 = Mathf.Min(num2, Mathf.Min(num3, num4));
		float fillAmount = Mathf.Min(num, 1f - num5);
		if (_segments == null)
		{
			return;
		}
		foreach (ActiveSegment segment in _segments)
		{
			segment.Billboard?.UpdateRing(fillAmount);
		}
	}

	private void Update()
	{
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		if (_isLocked)
		{
			_lockoutTimer -= Time.unscaledDeltaTime;
			UpdateRingProgress();
			if (_lockoutTimer <= 0f)
			{
				Unlock();
			}
			else
			{
				_lockPulseTimer -= Time.unscaledDeltaTime;
				if (_lockPulseTimer <= 0f)
				{
					_lockPulseTimer = 0.5f;
					if ((Object)(object)_drillNameBillboard != (Object)null)
					{
						StunShockwave.Spawn(((Component)_drillNameBillboard).transform.position, LockOrange);
					}
				}
			}
		}
		if (_isStunned)
		{
			_stunTimer -= Time.unscaledDeltaTime;
			if (_stunTimer <= 0f)
			{
				EndStun();
			}
			else if (!_isKillBillStunned)
			{
				_regularStunPulseTimer -= Time.unscaledDeltaTime;
				if (_regularStunPulseTimer <= 0f)
				{
					_regularStunPulseTimer = 0.5f;
					if ((Object)(object)_drillNameBillboard != (Object)null)
					{
						StunShockwave.Spawn(((Component)_drillNameBillboard).transform.position);
					}
				}
			}
		}
		if (!_isKillBillStunned)
		{
			return;
		}
		_killBillStunTimer -= Time.unscaledDeltaTime;
		if (_killBillStunTimer <= 0f)
		{
			EndKillBillStun();
			return;
		}
		_killBillPulseTimer -= Time.unscaledDeltaTime;
		if (_killBillPulseTimer <= 0f)
		{
			_killBillPulseTimer = 0.5f;
			if ((Object)(object)_drillNameBillboard != (Object)null)
			{
				StunShockwave.Spawn(((Component)_drillNameBillboard).transform.position, KillBillBlue);
			}
		}
		_glitchTimer -= Time.unscaledDeltaTime;
		if (_glitchTimer <= 0f)
		{
			_glitchTimer = 0.04f;
			_drillNameBillboard?.SetLabelTextQuiet(RandomGlitchString(), KillBillBlue);
		}
	}

	private void Unlock()
	{
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Invalid comparison between Unknown and I4
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		_isLocked = false;
		_lockoutTimer = 0f;
		_globalBodyHitsReceived = 0;
		_globalHeadHitsReceived = 0;
		_globalAnyHitsReceived = 0;
		if (_segments == null || _definition == null)
		{
			return;
		}
		foreach (ActiveSegment segment in _segments)
		{
			segment.Billboard?.HideRing();
		}
		if (_definition.DrillType == DrillType.ElPresidente)
		{
			foreach (ActiveSegment segment2 in _segments)
			{
				if ((int)segment2.Definition.BodyPart == 1)
				{
					segment2.CurrentColor = SegmentColor.Yellow;
					segment2.Billboard?.UpdateColor(SegmentColor.Yellow);
					break;
				}
			}
			return;
		}
		if (_definition.DrillType != DrillType.BoxDrill)
		{
			return;
		}
		foreach (ActiveSegment segment3 in _segments)
		{
			if ((int)segment3.Definition.BodyPart != 0)
			{
				continue;
			}
			segment3.CurrentColor = SegmentColor.Yellow;
			segment3.Billboard?.UpdateColor(SegmentColor.Yellow);
			SegmentBillboard billboard = segment3.Billboard;
			if (billboard != null)
			{
				GameObject gameObject = ((Component)billboard).gameObject;
				if (gameObject != null)
				{
					gameObject.SetActive(true);
				}
			}
			break;
		}
	}

	private void KillSosigFromDrill()
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		if (_definition != null && _definition.DrillType == DrillType.BillDrill)
		{
			float radius = ((TrainingModePlugin.CfgKillBillRadius != null) ? TrainingModePlugin.CfgKillBillRadius.Value : 8f);
			KillBillExplosion.Spawn(((Component)this).transform.position, radius);
		}
		Sosig component = ((Component)this).GetComponent<Sosig>();
		if ((Object)(object)component != (Object)null && (Object)(object)DrillManager.Instance != (Object)null)
		{
			DrillManager.Instance.ScheduleKill(component);
		}
		ClearDrill();
	}

	public void ClearDrill()
	{
		EndStun();
		EndKillBillStun();
		if (_segments != null)
		{
			foreach (ActiveSegment segment in _segments)
			{
				segment.Billboard?.DestroySelf();
			}
			_segments.Clear();
			_segments = null;
		}
		_drillNameBillboard?.DestroySelf();
		_drillNameBillboard = null;
		_isLocked = false;
		_lockoutUsed = false;
		_lockTriggerCount = -1;
		_globalBodyHitsReceived = 0;
		_globalHeadHitsReceived = 0;
		_globalAnyHitsReceived = 0;
		_isStunned = false;
		_stunTimer = 0f;
		_isKillBillStunned = false;
		_killBillStunTimer = 0f;
		ResetStunTracking();
		_definition = null;
		if ((Object)(object)DrillManager.Instance != (Object)null)
		{
			DrillManager.Instance.UnregisterComponent(this);
		}
	}

	private void ResetStunTracking()
	{
		_torsoHit1Time = -99f;
		_torsoHit2Time = -99f;
		_torsoStunLastTime = -99f;
		_lowerHit1Time = -99f;
		_lowerHit2Time = -99f;
		_lowerStunLastTime = -99f;
	}

	private void OnDestroy()
	{
		ClearDrill();
	}

	private static string RandomGlitchString()
	{
		char[] array = new char[8];
		for (int i = 0; i < 8; i++)
		{
			array[i] = GlitchChars[Random.Range(0, GlitchChars.Length)];
		}
		return new string(array);
	}
}
public class StunShockwave : MonoBehaviour
{
	private const float Duration = 0.4f;

	private const int Segments = 32;

	private const float InnerFrac = 0.75f;

	private float _timer;

	private float _maxRadius;

	private Color _spawnColor;

	private Material _mat;

	public static void Spawn(Vector3 worldPos)
	{
		//IL_0000: 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)
		Spawn(worldPos, new Color(1f, 44f / 51f, 0f));
	}

	public static void Spawn(Vector3 worldPos, Color color, float maxRadius = 0.7f)
	{
		//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_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_001d: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("TM_StunShockwave");
		val.transform.position = worldPos;
		StunShockwave stunShockwave = val.AddComponent<StunShockwave>();
		stunShockwave._spawnColor = color;
		stunShockwave._maxRadius = maxRadius;
	}

	private void Start()
	{
		//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_001c: 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_0050: Expected O, but got Unknown
		//IL_0057: 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)
		GameObject val = new GameObject("Ring");
		val.transform.SetParent(((Component)this).transform, false);
		MeshFilter val2 = val.AddComponent<MeshFilter>();
		MeshRenderer obj = val.AddComponent<MeshRenderer>();
		val2.mesh = BuildRingMesh();
		_mat = new Material(Shader.Find("Unlit/Color"))
		{
			hideFlags = (HideFlags)61
		};
		_mat.color = _spawnColor;
		((Renderer)obj).material = _mat;
		((Component)this).transform.localScale = Vector3.zero;
	}

	private void OnDestroy()
	{
		if ((Object)(object)_mat != (Object)null)
		{
			Object.Destroy((Object)(object)_mat);
		}
	}

	private void Update()
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		_timer += Time.unscaledDeltaTime;
		float num = _timer / 0.4f;
		if (num >= 1f)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		float num2 = Mathf.Lerp(0f, _maxRadius, num);
		((Component)this).transform.localScale = new Vector3(num2, num2, num2);
	}

	private static Mesh BuildRingMesh()
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Expected O, but got Unknown
		Vector3[] array = (Vector3[])(object)new Vector3[64];
		int[] array2 = new int[192];
		for (int i = 0; i < 32; i++)
		{
			float num = (float)i * 2f * (float)Math.PI / 32f;
			float num2 = Mathf.Cos(num);
			float num3 = Mathf.Sin(num);
			array[i] = new Vector3(num2, 0f, num3);
			array[i + 32] = new Vector3(num2 * 0.75f, 0f, num3 * 0.75f);
		}
		for (int j = 0; j < 32; j++)
		{
			int num4 = (j + 1) % 32;
			int num5 = j * 6;
			array2[num5] = j;
			array2[num5 + 1] = num4;
			array2[num5 + 2] = j + 32;
			array2[num5 + 3] = num4;
			array2[num5 + 4] = num4 + 32;
			array2[num5 + 5] = j + 32;
		}
		Mesh val = new Mesh
		{
			hideFlags = (HideFlags)61,
			vertices = array,
			triangles = array2
		};
		val.RecalculateNormals();
		return val;
	}
}
internal static class TrainingModePatches
{
	[HarmonyPatch(typeof(SosigLink), "Damage")]
	[HarmonyPrefix]
	private static bool BlockSosigDamage(SosigLink __instance, Damage d)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Invalid comparison between Unknown and I4
		if ((Object)(object)DrillManager.Instance == (Object)null)
		{
			return true;
		}
		if (!DrillManager.Instance.TrainingModeActive)
		{
			return true;
		}
		Sosig s = __instance.S;
		SosigDrillComponent sosigDrillComponent = ((s != null) ? ((Component)s).GetComponent<SosigDrillComponent>() : null);
		if ((Object)(object)sosigDrillComponent != (Object)null && sosigDrillComponent.HasActiveDrill)
		{
			if ((int)d.Class == 1)
			{
				sosigDrillComponent.OnLinkHit(__instance);
			}
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(Sosig), "Start")]
	[HarmonyPostfix]
	private static void OnSosigStart(Sosig __instance)
	{
		if (!((Object)(object)DrillManager.Instance == (Object)null) && DrillManager.Instance.TrainingModeActive)
		{
			SosigDrillComponent sosigDrillComponent = ((Component)__instance).GetComponent<SosigDrillComponent>();
			if ((Object)(object)sosigDrillComponent == (Object)null)
			{
				sosigDrillComponent = ((Component)__instance).gameObject.AddComponent<SosigDrillComponent>();
			}
			DrillManager.Instance.AssignDrill(sosigDrillComponent);
		}
	}

	[HarmonyPatch(typeof(Sosig), "SosigDies")]
	[HarmonyPostfix]
	private static void OnSosigDied(Sosig __instance)
	{
		SosigDrillComponent component = ((Component)__instance).GetComponent<SosigDrillComponent>();
		if ((Object)(object)component != (Object)null)
		{
			component.ClearDrill();
		}
	}
}
public class WristMenuSection_Training : FVRWristMenuSection
{
	public Text TXT_Training;

	public Text TXT_BabyPanda;

	public Text TXT_BillDrill;

	public Text TXT_Mozambique;

	public Text TXT_ElPresidente;

	public Text TXT_BoxDrill;

	public Text TXT_Invent60;

	public override void OnHide()
	{
	}

	public void UpdateLabels()
	{
		DrillManager instance = DrillManager.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			if ((Object)(object)TXT_Training != (Object)null)
			{
				TXT_Training.text = "Training: " + (instance.TrainingModeActive ? "ON" : "OFF");
			}
			if ((Object)(object)TXT_BabyPanda != (Object)null)
			{
				TXT_BabyPanda.text = "Baby Panda: " + (instance.BabyPandaEnabled ? "ON" : "OFF");
			}
			if ((Object)(object)TXT_BillDrill != (Object)null)
			{
				TXT_BillDrill.text = "Bill Drill: " + (instance.BillDrillEnabled ? "ON" : "OFF");
			}
			if ((Object)(object)TXT_Mozambique != (Object)null)
			{
				TXT_Mozambique.text = "Mozambique: " + (instance.MozambiqueEnabled ? "ON" : "OFF");
			}
			if ((Object)(object)TXT_ElPresidente != (Object)null)
			{
				TXT_ElPresidente.text = "El Presidente: " + (instance.ElPresidenteEnabled ? "ON" : "OFF");
			}
			if ((Object)(object)TXT_BoxDrill != (Object)null)
			{
				TXT_BoxDrill.text = "Box Drill: " + (instance.BoxDrillEnabled ? "ON" : "OFF");
			}
			if ((Object)(object)TXT_Invent60 != (Object)null)
			{
				TXT_Invent60.text = "Invent60: " + (instance.Invent60Enabled ? "ON" : "OFF");
			}
		}
	}
}
internal static class TrainingModeWristMenuPatch
{
	[HarmonyPatch(typeof(FVRWristMenu2), "Awake")]
	[HarmonyPostfix]
	private static void WristMenuAwake(FVRWristMenu2 __instance)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: 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_0089: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Expected O, but got Unknown
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Expected O, but got Unknown
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		FVRWristMenuSection val = null;
		for (int i = 0; i < __instance.Sections.Count; i++)
		{
			if (((object)__instance.Sections[i]).GetType().Name == "FVRWristMenuSection_Spawn")
			{
				val = __instance.Sections[i];
				break;
			}
		}
		if (!((Object)(object)val == (Object)null))
		{
			Transform transform = ((Component)val).transform;
			FVRWristMenuSection obj = Object.Instantiate<FVRWristMenuSection>(val, transform.position, transform.rotation, transform.parent);
			GameObject gameObject = ((Component)obj).gameObject;
			Object.Destroy((Object)obj);
			WristMenuSection_Training wristMenuSection_Training = gameObject.AddComponent<WristMenuSection_Training>();
			((FVRWristMenuSection)wristMenuSection_Training).ButtonText = "Training";
			((FVRWristMenuSection)wristMenuSection_Training).Menu = __instance;
			__instance.Sections.Add((FVRWristMenuSection)wristMenuSection_Training);
			__instance.RegenerateButtons();
			RectTransform val2 = (RectTransform)gameObject.transform;
			RectTransform val3 = (RectTransform)((Transform)val2).GetChild(0);
			float y = val2.sizeDelta.y;
			int childCount = ((Transform)val2).childCount;
			float num = val3.sizeDelta.y * ((Transform)val3).localScale.y;
			float num2 = ((childCount > 0) ? ((y - num * (float)childCount) / (float)(childCount + 2)) : 4f);
			float num3 = num + num2;
			for (int num4 = ((Transform)val2).childCount - 1; num4 >= 1; num4--)
			{
				Object.DestroyImmediate((Object)((Component)((Transform)val2).GetChild(num4)).gameObject);
			}
			wristMenuSection_Training.TXT_Training = WireButton(val3, wristMenuSection_Training, 0);
			wristMenuSection_Training.TXT_BabyPanda = WireButton(AddBtn(val3, val2), wristMenuSection_Training, 1);
			wristMenuSection_Training.TXT_BillDrill = WireButton(AddBtn(val3, val2), wristMenuSection_Training, 2);
			wristMenuSection_Training.TXT_Mozambique = WireButton(AddBtn(val3, val2), wristMenuSection_Training, 3);
			wristMenuSection_Training.TXT_ElPresidente = WireButton(AddBtn(val3, val2), wristMenuSection_Training, 4);
			wristMenuSection_Training.TXT_BoxDrill = WireButton(AddBtn(val3, val2), wristMenuSection_Training, 5);
			wristMenuSection_Training.TXT_Invent60 = WireButton(AddBtn(val3, val2), wristMenuSection_Training, 6);
			val2.sizeDelta = new Vector2(val2.sizeDelta.x, 7f * num3 + num2 * 2f);
			float num5 = num3 * 0.5f + num2;
			for (int j = 0; j < 7; j++)
			{
				((Transform)val2).GetChild(j).localPosition = new Vector3(0f, num5, 0f);
				num5 += num3;
			}
			wristMenuSection_Training.UpdateLabels();
		}
	}

	private static RectTransform AddBtn(RectTransform template, RectTransform parent)
	{
		//IL_0007: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		return (RectTransform)Object.Instantiate<GameObject>(((Component)template).gameObject, ((Transform)template).position, ((Transform)template).rotation, (Transform)(object)parent).transform;
	}

	private static Text WireButton(RectTransform btn, WristMenuSection_Training sec, int idx)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		Text componentInChildren = ((Component)btn).GetComponentInChildren<Text>();
		Button component = ((Component)btn).GetComponent<Button>();
		component.onClick = new ButtonClickedEvent();
		((UnityEvent)component.onClick).AddListener((UnityAction)delegate
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			SM.PlayGlobalUISound((GlobalUISound)0, ((Transform)btn).position);
			OnClick(sec, idx);
		});
		return componentInChildren;
	}

	private static void OnClick(WristMenuSection_Training sec, int idx)
	{
		DrillManager instance = DrillManager.Instance;
		if (!((Object)(object)instance == (Object)null))
		{
			switch (idx)
			{
			case 0:
				instance.OnTrainingModeToggled(!instance.TrainingModeActive);
				break;
			case 1:
				instance.BabyPandaEnabled = !instance.BabyPandaEnabled;
				instance.RecalculateWeights();
				break;
			case 2:
				instance.BillDrillEnabled = !instance.BillDrillEnabled;
				instance.RecalculateWeights();
				break;
			case 3:
				instance.MozambiqueEnabled = !instance.MozambiqueEnabled;
				instance.RecalculateWeights();
				break;
			case 4:
				instance.ElPresidenteEnabled = !instance.ElPresidenteEnabled;
				instance.RecalculateWeights();
				break;
			case 5:
				instance.BoxDrillEnabled = !instance.BoxDrillEnabled;
				instance.RecalculateWeights();
				break;
			case 6:
				instance.Invent60Enabled = !instance.Invent60Enabled;
				instance.RecalculateWeights();
				break;
			}
			sec.UpdateLabels();
		}
	}
}