Decompiled source of Helldivers Stratagem v1.0.1

Helldivers_Stratagem.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using OtherLoader;
using UnityEngine;

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace Packer.Helldivers_Stratagem;

[BepInPlugin("Packer.Helldivers_Stratagem", "Helldivers_Stratagem", "1.0.1")]
[BepInProcess("h3vr.exe")]
[Description("Built with MeatKit")]
[BepInDependency("h3vr.otherloader", "1.3.0")]
public class Helldivers_StratagemPlugin : BaseUnityPlugin
{
	private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

	internal static ManualLogSource Logger;

	private void Awake()
	{
		Logger = ((BaseUnityPlugin)this).Logger;
		LoadAssets();
	}

	private void LoadAssets()
	{
		Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Packer.Helldivers_Stratagem");
		OtherLoader.RegisterDirectLoad(BasePath, "Packer.Helldivers_Stratagem", "", "", "packer.helldiver_stratagem", "");
	}
}
public class CuttableMesh
{
	private MeshRenderer inputMeshRenderer;

	private bool hasUvs;

	private bool hasUv1s;

	private bool hasColours;

	private List<CuttableSubMesh> subMeshes;

	public CuttableMesh(Mesh inputMesh)
	{
		Init(inputMesh, ((Object)inputMesh).name);
	}

	public CuttableMesh(MeshRenderer input)
	{
		inputMeshRenderer = input;
		MeshFilter component = ((Component)input).GetComponent<MeshFilter>();
		Mesh sharedMesh = component.sharedMesh;
		Init(sharedMesh, ((Object)input).name);
	}

	public CuttableMesh(CuttableMesh inputMesh, List<CuttableSubMesh> newSubMeshes)
	{
		inputMeshRenderer = inputMesh.inputMeshRenderer;
		hasUvs = inputMesh.hasUvs;
		hasUv1s = inputMesh.hasUv1s;
		hasColours = inputMesh.hasColours;
		subMeshes = new List<CuttableSubMesh>();
		subMeshes.AddRange(newSubMeshes);
	}

	private void Init(Mesh inputMesh, string debugName)
	{
		subMeshes = new List<CuttableSubMesh>();
		if (inputMesh.isReadable)
		{
			Vector3[] vertices = inputMesh.vertices;
			Vector3[] normals = inputMesh.normals;
			Vector2[] uv = inputMesh.uv;
			Vector2[] uv2 = inputMesh.uv2;
			Color32[] colors = inputMesh.colors32;
			hasUvs = uv != null && uv.Length > 0;
			hasUv1s = uv2 != null && uv2.Length > 0;
			hasColours = colors != null && colors.Length > 0;
			for (int i = 0; i < inputMesh.subMeshCount; i++)
			{
				int[] indices = inputMesh.GetIndices(i);
				CuttableSubMesh item = new CuttableSubMesh(indices, vertices, normals, colors, uv, uv2);
				subMeshes.Add(item);
			}
		}
		else
		{
			Debug.LogError((object)("CuttableMesh's input mesh is not readable: " + debugName), (Object)(object)inputMesh);
		}
	}

	public void Add(CuttableMesh other)
	{
		if (subMeshes.Count != other.subMeshes.Count)
		{
			throw new Exception("Mismatched submesh count");
		}
		for (int i = 0; i < subMeshes.Count; i++)
		{
			subMeshes[i].Add(other.subMeshes[i]);
		}
	}

	public int NumSubMeshes()
	{
		return subMeshes.Count;
	}

	public bool HasUvs()
	{
		return hasUvs;
	}

	public bool HasColours()
	{
		return hasColours;
	}

	public List<CuttableSubMesh> GetSubMeshes()
	{
		return subMeshes;
	}

	public CuttableSubMesh GetSubMesh(int index)
	{
		return subMeshes[index];
	}

	public Transform GetTransform()
	{
		if ((Object)(object)inputMeshRenderer != (Object)null)
		{
			return ((Component)inputMeshRenderer).transform;
		}
		return null;
	}

	public MeshRenderer ConvertToRenderer(string newObjectName)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		//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_005d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		Mesh val = CreateMesh();
		if (val.vertexCount == 0)
		{
			return null;
		}
		GameObject val2 = new GameObject(newObjectName);
		val2.transform.SetParent(((Component)inputMeshRenderer).transform);
		val2.transform.localPosition = Vector3.zero;
		val2.transform.localRotation = Quaternion.identity;
		val2.transform.localScale = Vector3.one;
		MeshFilter val3 = val2.AddComponent<MeshFilter>();
		val3.mesh = val;
		MeshRenderer val4 = val2.AddComponent<MeshRenderer>();
		((Renderer)val4).shadowCastingMode = ((Renderer)inputMeshRenderer).shadowCastingMode;
		((Renderer)val4).reflectionProbeUsage = ((Renderer)inputMeshRenderer).reflectionProbeUsage;
		((Renderer)val4).lightProbeUsage = ((Renderer)inputMeshRenderer).lightProbeUsage;
		((Renderer)val4).sharedMaterials = ((Renderer)inputMeshRenderer).sharedMaterials;
		return val4;
	}

	public Mesh CreateMesh()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Expected O, but got Unknown
		Mesh val = new Mesh();
		int num = 0;
		for (int i = 0; i < subMeshes.Count; i++)
		{
			num += subMeshes[i].NumIndices();
		}
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		List<Color32> list3 = ((!hasColours) ? null : new List<Color32>());
		List<Vector2> list4 = ((!hasUvs) ? null : new List<Vector2>());
		List<Vector2> list5 = ((!hasUv1s) ? null : new List<Vector2>());
		List<int> list6 = new List<int>();
		foreach (CuttableSubMesh subMesh in subMeshes)
		{
			list6.Add(list.Count);
			subMesh.AddTo(list, list2, list3, list4, list5);
		}
		val.vertices = list.ToArray();
		val.normals = list2.ToArray();
		val.colors32 = ((!hasColours) ? null : list3.ToArray());
		val.uv = ((!hasUvs) ? null : list4.ToArray());
		val.uv2 = ((!hasUv1s) ? null : list5.ToArray());
		val.subMeshCount = subMeshes.Count;
		for (int j = 0; j < subMeshes.Count; j++)
		{
			CuttableSubMesh cuttableSubMesh = subMeshes[j];
			int num2 = list6[j];
			int[] array = cuttableSubMesh.GenIndices();
			for (int k = 0; k < array.Length; k++)
			{
				array[k] += num2;
			}
			val.SetTriangles(array, j, true);
		}
		return val;
	}
}
public class CuttableSubMesh
{
	private List<Vector3> vertices;

	private List<Vector3> normals;

	private List<Color32> colours;

	private List<Vector2> uvs;

	private List<Vector2> uv1s;

	public CuttableSubMesh(bool hasNormals, bool hasColours, bool hasUvs, bool hasUv1)
	{
		vertices = new List<Vector3>();
		if (hasNormals)
		{
			normals = new List<Vector3>();
		}
		if (hasColours)
		{
			colours = new List<Color32>();
		}
		if (hasUvs)
		{
			uvs = new List<Vector2>();
		}
		if (hasUv1)
		{
			uv1s = new List<Vector2>();
		}
	}

	public CuttableSubMesh(int[] indices, Vector3[] inputVertices, Vector3[] inputNormals, Color32[] inputColours, Vector2[] inputUvs, Vector2[] inputUv1)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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_0124: Unknown result type (might be due to invalid IL or missing references)
		vertices = new List<Vector3>();
		if (inputNormals != null && inputNormals.Length > 0)
		{
			normals = new List<Vector3>();
		}
		if (inputColours != null && inputColours.Length > 0)
		{
			colours = new List<Color32>();
		}
		if (inputUvs != null && inputUvs.Length > 0)
		{
			uvs = new List<Vector2>();
		}
		if (inputUv1 != null && inputUv1.Length > 0)
		{
			uv1s = new List<Vector2>();
		}
		foreach (int num in indices)
		{
			vertices.Add(inputVertices[num]);
			if (normals != null)
			{
				normals.Add(inputNormals[num]);
			}
			if (colours != null)
			{
				colours.Add(inputColours[num]);
			}
			if (uvs != null)
			{
				uvs.Add(inputUvs[num]);
			}
			if (uv1s != null)
			{
				uv1s.Add(inputUv1[num]);
			}
		}
	}

	public void Add(CuttableSubMesh other)
	{
		for (int i = 0; i < other.vertices.Count; i++)
		{
			CopyVertex(i, other);
		}
	}

	public int NumVertices()
	{
		return vertices.Count;
	}

	public Vector3 GetVertex(int index)
	{
		//IL_0008: 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_0013: Unknown result type (might be due to invalid IL or missing references)
		return vertices[index];
	}

	public bool HasNormals()
	{
		return normals != null;
	}

	public bool HasColours()
	{
		return colours != null;
	}

	public bool HasUvs()
	{
		return uvs != null;
	}

	public bool HasUv1()
	{
		return uv1s != null;
	}

	public void CopyVertex(int srcIndex, CuttableSubMesh srcMesh)
	{
		//IL_000e: 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_0052: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		vertices.Add(srcMesh.vertices[srcIndex]);
		if (normals != null)
		{
			normals.Add(srcMesh.normals[srcIndex]);
		}
		if (colours != null)
		{
			colours.Add(srcMesh.colours[srcIndex]);
		}
		if (uvs != null)
		{
			uvs.Add(srcMesh.uvs[srcIndex]);
		}
		if (uv1s != null)
		{
			uv1s.Add(srcMesh.uv1s[srcIndex]);
		}
	}

	public void AddInterpolatedVertex(int i0, int i1, float weight, CuttableSubMesh srcMesh)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: 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)
		Vector3 vertex = srcMesh.GetVertex(i0);
		Vector3 vertex2 = srcMesh.GetVertex(i1);
		vertices.Add(Vector3.Lerp(vertex, vertex2, weight));
		if (normals != null)
		{
			List<Vector3> list = normals;
			Vector3 val = Vector3.Lerp(srcMesh.normals[i0], srcMesh.normals[i1], weight);
			list.Add(((Vector3)(ref val)).normalized);
		}
		if (colours != null)
		{
			colours.Add(Color32.Lerp(srcMesh.colours[i0], srcMesh.colours[i1], weight));
		}
		if (uvs != null)
		{
			uvs.Add(Vector2.Lerp(srcMesh.uvs[i0], srcMesh.uvs[i1], weight));
		}
		if (uv1s != null)
		{
			uv1s.Add(Vector2.Lerp(srcMesh.uv1s[i0], srcMesh.uv1s[i1], weight));
		}
	}

	public void AddTo(List<Vector3> destVertices, List<Vector3> destNormals, List<Color32> destColours, List<Vector2> destUvs, List<Vector2> destUv1s)
	{
		destVertices.AddRange(vertices);
		if (normals != null)
		{
			destNormals.AddRange(normals);
		}
		if (colours != null)
		{
			destColours.AddRange(colours);
		}
		if (uvs != null)
		{
			destUvs.AddRange(uvs);
		}
		if (uv1s != null)
		{
			destUv1s.AddRange(uv1s);
		}
	}

	public int NumIndices()
	{
		return vertices.Count;
	}

	public int[] GenIndices()
	{
		int[] array = new int[vertices.Count];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = i;
		}
		return array;
	}
}
public enum VertexClassification
{
	Front = 1,
	Back = 2,
	OnPlane = 4
}
public class MeshCutter
{
	private CuttableMesh inputMesh;

	private List<CuttableSubMesh> outputFrontSubMeshes;

	private List<CuttableSubMesh> outputBackSubMeshes;

	public void Cut(CuttableMesh input, Plane worldCutPlane)
	{
		//IL_0067: 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_0038: 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_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		inputMesh = input;
		outputFrontSubMeshes = new List<CuttableSubMesh>();
		outputBackSubMeshes = new List<CuttableSubMesh>();
		Transform transform = inputMesh.GetTransform();
		Plane cutPlane = default(Plane);
		if ((Object)(object)transform != (Object)null)
		{
			Vector3 val = transform.InverseTransformPoint(ClosestPointOnPlane(worldCutPlane, Vector3.zero));
			Vector3 val2 = transform.InverseTransformDirection(((Plane)(ref worldCutPlane)).normal);
			((Plane)(ref cutPlane))..ctor(val2, val);
		}
		else
		{
			cutPlane = worldCutPlane;
		}
		foreach (CuttableSubMesh subMesh in input.GetSubMeshes())
		{
			Cut(subMesh, cutPlane);
		}
	}

	private static Vector3 ClosestPointOnPlane(Plane plane, Vector3 point)
	{
		//IL_0003: 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_0032: 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_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: 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_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_004b: Unknown result type (might be due to invalid IL or missing references)
		float distanceToPoint = ((Plane)(ref plane)).GetDistanceToPoint(point);
		if (((Plane)(ref plane)).GetSide(point))
		{
			return point - ((Plane)(ref plane)).normal * distanceToPoint;
		}
		return point + ((Plane)(ref plane)).normal * distanceToPoint;
	}

	public CuttableMesh GetFrontOutput()
	{
		return new CuttableMesh(inputMesh, outputFrontSubMeshes);
	}

	public CuttableMesh GetBackOutput()
	{
		return new CuttableMesh(inputMesh, outputBackSubMeshes);
	}

	private void Cut(CuttableSubMesh inputSubMesh, Plane cutPlane)
	{
		//IL_004f: 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_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_0068: 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_006d: 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_0078: 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_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: 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_02be: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02df: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_029d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		bool hasNormals = inputSubMesh.HasNormals();
		bool hasColours = inputSubMesh.HasColours();
		bool hasUvs = inputSubMesh.HasUvs();
		bool hasUv = inputSubMesh.HasUv1();
		CuttableSubMesh cuttableSubMesh = new CuttableSubMesh(hasNormals, hasColours, hasUvs, hasUv);
		CuttableSubMesh cuttableSubMesh2 = new CuttableSubMesh(hasNormals, hasColours, hasUvs, hasUv);
		for (int i = 0; i < inputSubMesh.NumVertices(); i += 3)
		{
			int num = i;
			int num2 = i + 1;
			int num3 = i + 2;
			Vector3 vertex = inputSubMesh.GetVertex(num);
			Vector3 vertex2 = inputSubMesh.GetVertex(num2);
			Vector3 vertex3 = inputSubMesh.GetVertex(num3);
			VertexClassification vertexClassification = Classify(vertex, cutPlane);
			VertexClassification vertexClassification2 = Classify(vertex2, cutPlane);
			VertexClassification vertexClassification3 = Classify(vertex3, cutPlane);
			int numFront = 0;
			int numBehind = 0;
			CountSides(vertexClassification, ref numFront, ref numBehind);
			CountSides(vertexClassification2, ref numFront, ref numBehind);
			CountSides(vertexClassification3, ref numFront, ref numBehind);
			if (numFront > 0 && numBehind == 0)
			{
				KeepTriangle(num, num2, num3, inputSubMesh, cuttableSubMesh);
			}
			else if (numFront == 0 && numBehind > 0)
			{
				KeepTriangle(num, num2, num3, inputSubMesh, cuttableSubMesh2);
			}
			else if (numFront == 2 && numBehind == 1)
			{
				if (vertexClassification == VertexClassification.Back)
				{
					SplitA(num, num2, num3, inputSubMesh, cutPlane, cuttableSubMesh2, cuttableSubMesh);
				}
				else if (vertexClassification2 == VertexClassification.Back)
				{
					SplitA(num2, num3, num, inputSubMesh, cutPlane, cuttableSubMesh2, cuttableSubMesh);
				}
				else
				{
					SplitA(num3, num, num2, inputSubMesh, cutPlane, cuttableSubMesh2, cuttableSubMesh);
				}
			}
			else if (numFront == 1 && numBehind == 2)
			{
				if (vertexClassification == VertexClassification.Front)
				{
					SplitA(num, num2, num3, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
				}
				else if (vertexClassification2 == VertexClassification.Front)
				{
					SplitA(num2, num3, num, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
				}
				else
				{
					SplitA(num3, num, num2, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
				}
			}
			else if (numFront == 1 && numBehind == 1)
			{
				if (vertexClassification == VertexClassification.OnPlane)
				{
					if (vertexClassification3 == VertexClassification.Front)
					{
						SplitB(num3, num, num2, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
					}
					else
					{
						SplitBFlipped(num2, num3, num, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
					}
					continue;
				}
				switch (vertexClassification2)
				{
				case VertexClassification.OnPlane:
					if (vertexClassification == VertexClassification.Front)
					{
						SplitB(num, num2, num3, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
					}
					else
					{
						SplitBFlipped(num3, num, num2, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
					}
					break;
				case VertexClassification.Front:
					SplitB(num2, num3, num, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
					break;
				default:
					SplitBFlipped(num, num2, num3, inputSubMesh, cutPlane, cuttableSubMesh, cuttableSubMesh2);
					break;
				}
			}
			else if (numFront == 0 && numBehind == 0)
			{
				Vector3 val = vertex2 - vertex;
				Vector3 val2 = vertex3 - vertex;
				Vector3 val3 = Vector3.Cross(val, val2);
				if (Vector3.Dot(val3, ((Plane)(ref cutPlane)).normal) > 0f)
				{
					KeepTriangle(num, num2, num3, inputSubMesh, cuttableSubMesh2);
				}
				else
				{
					KeepTriangle(num, num2, num3, inputSubMesh, cuttableSubMesh);
				}
			}
		}
		outputFrontSubMeshes.Add(cuttableSubMesh);
		outputBackSubMeshes.Add(cuttableSubMesh2);
	}

	private VertexClassification Classify(Vector3 vertex, Plane cutPlane)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(vertex.x, vertex.y, vertex.z);
		float distanceToPoint = ((Plane)(ref cutPlane)).GetDistanceToPoint(val);
		double num = 9.999999747378752E-06;
		if ((double)distanceToPoint > 0.0 - num && (double)distanceToPoint < num)
		{
			return VertexClassification.OnPlane;
		}
		if (distanceToPoint > 0f)
		{
			return VertexClassification.Front;
		}
		return VertexClassification.Back;
	}

	private void CountSides(VertexClassification c, ref int numFront, ref int numBehind)
	{
		switch (c)
		{
		case VertexClassification.Front:
			numFront++;
			break;
		case VertexClassification.Back:
			numBehind++;
			break;
		}
	}

	private void KeepTriangle(int i0, int i1, int i2, CuttableSubMesh inputSubMesh, CuttableSubMesh destSubMesh)
	{
		destSubMesh.CopyVertex(i0, inputSubMesh);
		destSubMesh.CopyVertex(i1, inputSubMesh);
		destSubMesh.CopyVertex(i2, inputSubMesh);
	}

	private void SplitA(int i0, int i1, int i2, CuttableSubMesh inputSubMesh, Plane cutPlane, CuttableSubMesh frontSubMesh, CuttableSubMesh backSubMesh)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_0016: 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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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: 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_002c: 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)
		Vector3 vertex = inputSubMesh.GetVertex(i0);
		Vector3 vertex2 = inputSubMesh.GetVertex(i1);
		Vector3 vertex3 = inputSubMesh.GetVertex(i2);
		CalcIntersection(vertex, vertex2, cutPlane, out var weight);
		CalcIntersection(vertex3, vertex, cutPlane, out var weight2);
		frontSubMesh.CopyVertex(i0, inputSubMesh);
		frontSubMesh.AddInterpolatedVertex(i0, i1, weight, inputSubMesh);
		frontSubMesh.AddInterpolatedVertex(i2, i0, weight2, inputSubMesh);
		backSubMesh.AddInterpolatedVertex(i0, i1, weight, inputSubMesh);
		backSubMesh.CopyVertex(i1, inputSubMesh);
		backSubMesh.CopyVertex(i2, inputSubMesh);
		backSubMesh.CopyVertex(i2, inputSubMesh);
		backSubMesh.AddInterpolatedVertex(i2, i0, weight2, inputSubMesh);
		backSubMesh.AddInterpolatedVertex(i0, i1, weight, inputSubMesh);
	}

	private void SplitB(int i0, int i1, int i2, CuttableSubMesh inputSubMesh, Plane cutPlane, CuttableSubMesh frontSubMesh, CuttableSubMesh backSubMesh)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		//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_001a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 vertex = inputSubMesh.GetVertex(i0);
		Vector3 vertex2 = inputSubMesh.GetVertex(i2);
		CalcIntersection(vertex2, vertex, cutPlane, out var weight);
		frontSubMesh.CopyVertex(i0, inputSubMesh);
		frontSubMesh.CopyVertex(i1, inputSubMesh);
		frontSubMesh.AddInterpolatedVertex(i2, i0, weight, inputSubMesh);
		backSubMesh.CopyVertex(i1, inputSubMesh);
		backSubMesh.CopyVertex(i2, inputSubMesh);
		backSubMesh.AddInterpolatedVertex(i2, i0, weight, inputSubMesh);
	}

	private void SplitBFlipped(int i0, int i1, int i2, CuttableSubMesh inputSubMesh, Plane cutPlane, CuttableSubMesh frontSubMesh, CuttableSubMesh backSubMesh)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		//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_001a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 vertex = inputSubMesh.GetVertex(i0);
		Vector3 vertex2 = inputSubMesh.GetVertex(i1);
		CalcIntersection(vertex, vertex2, cutPlane, out var weight);
		frontSubMesh.CopyVertex(i0, inputSubMesh);
		frontSubMesh.AddInterpolatedVertex(i0, i1, weight, inputSubMesh);
		frontSubMesh.CopyVertex(i2, inputSubMesh);
		backSubMesh.CopyVertex(i1, inputSubMesh);
		backSubMesh.CopyVertex(i2, inputSubMesh);
		backSubMesh.AddInterpolatedVertex(i0, i1, weight, inputSubMesh);
	}

	private Vector3 CalcIntersection(Vector3 v0, Vector3 v1, Plane plane, out float weight)
	{
		//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_0008: 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_0014: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: 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_004e: 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)
		Vector3 val = v1 - v0;
		float magnitude = ((Vector3)(ref val)).magnitude;
		Ray val2 = default(Ray);
		((Ray)(ref val2))..ctor(v0, val / magnitude);
		float num = default(float);
		((Plane)(ref plane)).Raycast(val2, ref num);
		Vector3 result = ((Ray)(ref val2)).origin + ((Ray)(ref val2)).direction * num;
		weight = num / magnitude;
		return result;
	}
}

Packer.StratagemLibrary.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using FistVR;
using Microsoft.CodeAnalysis;
using Sodalite.Api;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyCompany("Packer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Stratagem Grenade Library")]
[assembly: AssemblyFileVersion("0.9.0.0")]
[assembly: AssemblyInformationalVersion("0.9.0+78e50cca40828de686e7fafe5bafe30a70b33700")]
[assembly: AssemblyProduct("Packer.StratagemLibrary")]
[assembly: AssemblyTitle("Stratagem Library Plugin")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.9.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string id = null, string name = null, string version = null)
		{
		}
	}
}
namespace Stratagem
{
	public class ModLoader
	{
		public delegate void GameStateDelegate();

		[Serializable]
		public class ModData
		{
			public string name;

			public string directory;

			public AssetBundle bundle;

			public Stratagem_Package package;
		}

		public static bool modsLoaded = false;

		public static List<string> modDirectories = new List<string>();

		public static List<ModData> mods = new List<ModData>();

		public static event GameStateDelegate GameStateEvent;

		public static IEnumerator LoadModPackages()
		{
			StratagemPlugin.Logger.LogMessage((object)"Loading Stratagem Mod Packages");
			modDirectories = Directory.GetFiles(Paths.PluginPath, "*.stratagem", SearchOption.AllDirectories).ToList();
			for (int i = 0; i < modDirectories.Count; i++)
			{
				bool continueOut = false;
				for (int z = 0; z < mods.Count; z++)
				{
					if (mods[z].directory == modDirectories[i])
					{
						continueOut = true;
						break;
					}
				}
				if (continueOut)
				{
					continue;
				}
				StratagemPlugin.Logger.LogMessage((object)("Loading Stratagem Loading - " + modDirectories[i]));
				ModData newMod = new ModData
				{
					directory = modDirectories[i],
					name = Path.GetFileName(modDirectories[i])
				};
				AssetBundleCreateRequest asyncBundleRequest = AssetBundle.LoadFromFileAsync(newMod.directory);
				yield return asyncBundleRequest;
				AssetBundle localAssetBundle = asyncBundleRequest.assetBundle;
				if ((Object)(object)localAssetBundle == (Object)null)
				{
					StratagemPlugin.Logger.LogError((object)("Failed to load AssetBundle - " + modDirectories[i]));
					continue;
				}
				newMod.bundle = localAssetBundle;
				mods.Add(newMod);
				AssetBundleRequest assetRequest = localAssetBundle.LoadAssetWithSubAssetsAsync<Stratagem_Package>("Stratagem");
				yield return assetRequest;
				if (assetRequest == null)
				{
					Debug.LogError((object)("Map Generator - Missing Package " + modDirectories[i]));
				}
				else
				{
					newMod.package = assetRequest.asset as Stratagem_Package;
				}
			}
			StratagemPlugin.Logger.LogMessage((object)("Stratagem Loaded: " + mods.Count));
			yield return null;
			modsLoaded = true;
		}

		public IEnumerator LoadThemes(string[] loadThemes)
		{
			for (int x = 0; x < loadThemes.Length; x++)
			{
				for (int i = 0; i < mods.Count; i++)
				{
					if (mods[i] != null && !((Object)(object)mods[i].package == (Object)null) && !(loadThemes[x] == "") && mods[i].package.title == loadThemes[x])
					{
						yield return null;
						break;
					}
				}
			}
		}

		public void SoftUnloadAllMods()
		{
			for (int i = 0; i < mods.Count; i++)
			{
				mods[i].bundle.Unload(false);
			}
		}

		public void UnloadMods(bool unloadAllLoadedObjects)
		{
			for (int i = 0; i < mods.Count; i++)
			{
				mods[i].bundle.Unload(unloadAllLoadedObjects);
			}
		}

		private void OnDestroy()
		{
			for (int i = 0; i < mods.Count; i++)
			{
				mods[i].bundle.Unload(true);
			}
			mods.Clear();
		}
	}
	[BepInPlugin("Packer.StratagemPlugin", "StratagemPlugin", "1.0.1")]
	[BepInProcess("h3vr.exe")]
	public class StratagemPlugin : BaseUnityPlugin
	{
		public static StratagemPlugin instance;

		public static List<Sosig> sosigs = new List<Sosig>();

		private static bool sosigClearUpdate = false;

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			instance = this;
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(ModLoader.LoadModPackages());
			((MonoBehaviour)instance).StartCoroutine(SosigUpdate());
		}

		private void OnDestroy()
		{
			sosigs = null;
		}

		private void ReregisterSosigKillEvent(Scene current, Scene next)
		{
			if (!((Object)(object)GM.CurrentSceneSettings == (Object)null))
			{
			}
		}

		protected static IEnumerator SosigUpdate()
		{
			yield return (object)new WaitForSeconds(Random.Range(4f, 6f));
			if (sosigs != null)
			{
				for (int i = sosigs.Count - 1; i >= 0; i--)
				{
					ClearSosig(sosigs[i]);
				}
				((MonoBehaviour)instance).StartCoroutine(SosigUpdate());
			}
		}

		public static void AddSosig(Sosig s)
		{
			for (int num = sosigs.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)sosigs[num] == (Object)null)
				{
					sosigs.RemoveAt(num);
				}
			}
			sosigs.Add(s);
		}

		public static void ClearSosig(Sosig s)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (sosigs.Contains(s) && (int)s.BodyState == 3)
			{
				s.ClearSosig();
				sosigs.Remove(s);
			}
		}

		public static void DestroyObject(float time, GameObject gameObj)
		{
			((MonoBehaviour)instance).StartCoroutine(DelayDestroy(time, gameObj));
		}

		protected static IEnumerator DelayDestroy(float time, GameObject gameObj)
		{
			yield return (object)new WaitForSeconds(time);
			if ((Object)(object)gameObj != (Object)null)
			{
				Object.Destroy((Object)(object)gameObj);
			}
		}
	}
	public class Stratagem_Grenade : FVRPhysicalObject
	{
		[Header("Stratagem")]
		public string currentInput = "";

		private Stratagem_Package selected;

		private bool callingIn = false;

		[Header("Visuals")]
		public Animator ballAnimator;

		public LineRenderer beam;

		public MeshRenderer ballGlow;

		public LineRenderer lightGlow;

		public Material[] ballGlowMats;

		public Material[] ballBeamMats;

		public Material[] ballLightMats;

		public Color[] textColors;

		[Header("Hellpod")]
		public GameObject hellpod;

		public GameObject hellpodFlame;

		public GameObject hellpodLandingEffect;

		public GameObject hellpodLandedEffect;

		public AudioEvent hellpodLand;

		public Transform[] hellpodSpawnPoints;

		[Header("UI")]
		public GameObject inputUI;

		public GameObject stratagemsUI;

		public GameObject previewPrefab;

		[HideInInspector]
		public Dictionary<Stratagem_Package, Stratagem_Preview> previews = new Dictionary<Stratagem_Package, Stratagem_Preview>();

		public Image[] arrowInputs;

		public Sprite[] arrowSprites;

		[Header("Call In UI")]
		public Transform callIn;

		public Text callTitle;

		public Text callTimer;

		public Text callDistance;

		public Image callThumbnail;

		public Image callArrow;

		private float deployHeight = 1000f;

		private float deployTimer = 0f;

		private float headBallDistance = 1f;

		private Transform parentTarget;

		private Vector3 offset;

		[Header("Audio")]
		public AudioEvent AudEvent_Arrow;

		public AudioEvent AudEvent_Ready;

		public AudioEvent AudEvent_ReadyLoop;

		public AudioEvent AudEvent_Beacon;

		public AudioEvent AudEvent_HellpodDrop;

		[Header("Rattle")]
		public AudioEvent AudEvent_Rattle;

		public float RattleRadius = 0.2f;

		public float RattleHeight = 0.2f;

		private Vector3 m_rattlePos = Vector3.zero;

		private Vector3 m_rattleLastPos = Vector3.zero;

		private Vector3 m_rattleVel = Vector3.zero;

		private bool m_israttleSide = false;

		private bool m_wasrattleSide = false;

		private float m_rattleTime = 0.1f;

		public override void Start()
		{
			((FVRInteractiveObject)this).Start();
			for (int i = 0; i < arrowInputs.Length; i++)
			{
				((Component)arrowInputs[i]).gameObject.SetActive(false);
			}
			inputUI.SetActive(false);
			stratagemsUI.SetActive(false);
			((Component)ballGlow).gameObject.SetActive(false);
			((Component)lightGlow).gameObject.SetActive(false);
			((Component)beam).gameObject.SetActive(false);
			previewPrefab.SetActive(false);
			((Component)callIn).gameObject.SetActive(false);
			hellpod.SetActive(false);
			hellpodFlame.SetActive(false);
			hellpodLandingEffect.SetActive(false);
			hellpodLandedEffect.SetActive(false);
			SetupStratagems();
		}

		private void SetupStratagems()
		{
			for (int i = 0; i < ModLoader.mods.Count; i++)
			{
				Stratagem_Package package = ModLoader.mods[i].package;
				List<string> list = new List<string>();
				if (package.spawnObjectIDs != null)
				{
					for (int j = 0; j < package.spawnObjectIDs.Length; j++)
					{
						if (IM.OD.ContainsKey(package.spawnObjectIDs[j]))
						{
							list.Add(package.spawnObjectIDs[j]);
						}
					}
				}
				package.spawnObjectIDs = list.ToArray();
				string spawnBackpackID = "";
				if (package.spawnBackpackID != null && IM.OD.ContainsKey(package.spawnBackpackID))
				{
					spawnBackpackID = package.spawnBackpackID;
				}
				package.spawnBackpackID = spawnBackpackID;
				List<int> list2 = new List<int>();
				if (package.spawnSosigEnemyIDs != null)
				{
					for (int k = 0; k < package.spawnSosigEnemyIDs.Length; k++)
					{
						if (ManagerSingleton<IM>.Instance.odicSosigObjsByID.ContainsKey((SosigEnemyID)package.spawnSosigEnemyIDs[k]))
						{
							list2.Add(package.spawnSosigEnemyIDs[k]);
						}
					}
				}
				package.spawnSosigEnemyIDs = list2.ToArray();
				int num = 0;
				if (package.spawnPrefabs != null)
				{
					num = package.spawnPrefabs.Length;
				}
				else
				{
					package.spawnPrefabs = (GameObject[])(object)new GameObject[0];
				}
				int num2 = 0;
				if (package.spawnInstantPrefab != null)
				{
					num2 = package.spawnInstantPrefab.Length;
				}
				else
				{
					package.spawnInstantPrefab = (GameObject[])(object)new GameObject[0];
				}
				if (list.Count == 0 && num == 0 && num2 == 0 && list2.Count == 0)
				{
					continue;
				}
				Stratagem_Preview component = Object.Instantiate<GameObject>(previewPrefab, previewPrefab.transform.parent).GetComponent<Stratagem_Preview>();
				((Component)component).gameObject.SetActive(true);
				component.title.text = package.title;
				component.description.text = package.description;
				component.icon.sprite = package.icon;
				for (int l = 0; l < 10; l++)
				{
					if (l < package.inputs.Length)
					{
						component.arrows[l].sprite = arrowSprites[ArrowConvert(package.inputs[l].ToString())];
					}
					else
					{
						((Component)component.arrows[l]).gameObject.SetActive(false);
					}
				}
				component.package = package;
				previews.Add(package, component);
			}
		}

		private int ArrowConvert(string letter)
		{
			return letter switch
			{
				"D" => 1, 
				"L" => 2, 
				"R" => 3, 
				_ => 0, 
			};
		}

		private void Update()
		{
			//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_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_0051: 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_0096: 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_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			if (callingIn)
			{
				deployTimer = Mathf.Clamp(deployTimer - Time.deltaTime, 0f, float.PositiveInfinity);
				Vector3 val = ((Component)this).transform.position - GM.CurrentPlayerBody.Head.position;
				headBallDistance = Vector3.Magnitude(val);
				beam.widthMultiplier = Mathf.Min(0.175f, 0.175f * headBallDistance);
				Vector3 position = GM.CurrentPlayerBody.Head.position;
				position.y = ((Component)this).transform.position.y;
				((Component)this).transform.LookAt(position);
				if (deployTimer > 0.5f)
				{
					TimeSpan timeSpan = TimeSpan.FromSeconds(Mathf.CeilToInt(deployTimer));
					callTimer.text = "INBOUND " + $"{timeSpan.Minutes:00}:{timeSpan.Seconds:00}";
					((Component)beam).gameObject.SetActive(true);
				}
				else
				{
					callTimer.text = "IMPACT";
					((Component)beam).gameObject.SetActive(false);
				}
				if (selected.deployType == Stratagem_Package.DeployType.Hellpod && (Object)(object)hellpod.transform.parent == (Object)(object)((Component)this).transform)
				{
					hellpod.transform.localPosition = Vector3.Lerp(Vector3.up * deployHeight, Vector3.zero, Mathf.InverseLerp(selected.deployTimer, 0f, deployTimer));
				}
			}
			if (previews == null || previews.Count <= 0)
			{
				return;
			}
			foreach (Stratagem_Package key in previews.Keys)
			{
				previews.TryGetValue(key, out var value);
				if (!((Object)(object)value == (Object)null) && !((Object)(object)value.package == (Object)null))
				{
					if (value.package.timeout > Time.time)
					{
						((Component)value.cooldown).gameObject.SetActive(true);
						value.arrowsParent.gameObject.SetActive(false);
						TimeSpan timeSpan2 = TimeSpan.FromSeconds(Mathf.CeilToInt(Time.time - key.timeout));
						value.cooldown.text = "Cooldown T-" + $"{timeSpan2.Minutes:00}:{timeSpan2.Seconds:00}";
					}
					else
					{
						((Component)value.cooldown).gameObject.SetActive(false);
						value.arrowsParent.gameObject.SetActive(true);
					}
				}
			}
		}

		private void LateUpdate()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_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_005f: Unknown result type (might be due to invalid IL or missing references)
			if (callingIn || ((Component)callIn).gameObject.activeSelf)
			{
				if ((Object)(object)parentTarget != (Object)null)
				{
					((Component)this).transform.position = parentTarget.position + parentTarget.rotation * offset;
				}
				callIn.position = GM.CurrentPlayerBody.Head.position;
				callIn.LookAt(((Component)this).transform.position);
				Transform obj = callIn;
				obj.position += callIn.forward * 2f;
				callDistance.text = Mathf.FloorToInt(headBallDistance) + "m";
			}
		}

		private void SpawnPrefabs()
		{
			//IL_0030: 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)
			for (int i = 0; i < selected.spawnPrefabs.Length; i++)
			{
				if ((Object)(object)selected.spawnPrefabs[i] != (Object)null)
				{
					Object.Instantiate<GameObject>(selected.spawnPrefabs[i], ((Component)this).transform.position, Quaternion.identity);
				}
			}
		}

		private void SpawnInstantPrefabs()
		{
			//IL_0030: 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)
			for (int i = 0; i < selected.spawnInstantPrefab.Length; i++)
			{
				if ((Object)(object)selected.spawnInstantPrefab[i] != (Object)null)
				{
					Object.Instantiate<GameObject>(selected.spawnInstantPrefab[i], ((Component)this).transform.position, Quaternion.identity);
				}
			}
		}

		private void SpawnSosigs()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_002d: 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)
			//IL_003b: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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)
			SpawnOptions val = new SpawnOptions
			{
				SpawnState = (SosigOrder)1,
				SpawnActivated = true,
				EquipmentMode = (EquipmentSlots)7,
				SpawnWithFullAmmo = true
			};
			Vector3 val2 = ((Component)this).transform.position;
			NavMeshHit val3 = default(NavMeshHit);
			for (int i = 0; i < selected.spawnSosigEnemyIDs.Length; i++)
			{
				if (NavMesh.SamplePosition(val2, ref val3, 15f, -1))
				{
					val2 = ((NavMeshHit)(ref val3)).position;
				}
				Sosig val4 = SosigAPI.Spawn(ManagerSingleton<IM>.Instance.odicSosigObjsByID[(SosigEnemyID)selected.spawnSosigEnemyIDs[i]], val, val2, ((Component)this).transform.rotation);
				val4.UpdateGuardPoint(val2);
				StratagemPlugin.AddSosig(val4);
				NavMeshAgent component = ((Component)val4).GetComponent<NavMeshAgent>();
				component.obstacleAvoidanceType = (ObstacleAvoidanceType)1;
				val2 += ((FVRInteractiveObject)this).Transform.forward;
			}
		}

		private void SpawnObjectIDs()
		{
			//IL_0077: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			FVRObject value = null;
			PlayerBackPack val = null;
			if (selected.spawnBackpackID != null && selected.spawnBackpackID != "" && IM.OD.TryGetValue(selected.spawnBackpackID, out value) && (Object)(object)value != (Object)null && (Object)(object)((AnvilAsset)value).GetGameObject() != (Object)null)
			{
				val = Object.Instantiate<GameObject>(((AnvilAsset)value).GetGameObject(), hellpodSpawnPoints[0].position, hellpodSpawnPoints[0].rotation).GetComponent<PlayerBackPack>();
			}
			FVRObject value2 = null;
			int num = 0;
			for (int i = 0; i < selected.spawnObjectIDs.Length; i++)
			{
				if (!IM.OD.TryGetValue(selected.spawnObjectIDs[i], out value2))
				{
					Debug.Log((object)("Stratagem: Cannot find object with id: " + selected.spawnObjectIDs[i]));
					continue;
				}
				GameObject val2 = null;
				if ((Object)(object)((AnvilAsset)value2).GetGameObject() != (Object)null)
				{
					val2 = Object.Instantiate<GameObject>(((AnvilAsset)value2).GetGameObject(), hellpodSpawnPoints[num].position + Vector3.up * 0.25f * (float)i, hellpodSpawnPoints[num].rotation);
				}
				FVRPhysicalObject component = val2.GetComponent<FVRPhysicalObject>();
				if ((Object)(object)val != (Object)null && (Object)(object)component != (Object)null)
				{
					for (int j = 0; j < ((FVRPhysicalObject)val).Slots.Length; j++)
					{
						if (!((Object)(object)((FVRPhysicalObject)val).Slots[j].HeldObject != (Object)null) && component.Size <= ((FVRPhysicalObject)val).Slots[j].SizeLimit)
						{
							component.SetQuickBeltSlot(((FVRPhysicalObject)val).Slots[j]);
							break;
						}
					}
				}
				num = ((num + 1 < hellpodSpawnPoints.Length) ? (num + 1) : 0);
			}
		}

		public void InputDirection(string direction)
		{
			//IL_01ad: 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)
			currentInput += direction;
			bool flag = false;
			for (int i = 0; i < arrowInputs.Length; i++)
			{
				if (i < currentInput.Length)
				{
					arrowInputs[i].sprite = arrowSprites[ArrowConvert(currentInput[i].ToString())];
					((Component)arrowInputs[i]).gameObject.SetActive(true);
				}
				else
				{
					((Component)arrowInputs[i]).gameObject.SetActive(false);
				}
			}
			foreach (ModLoader.ModData mod in ModLoader.mods)
			{
				if (mod.package.inputs.Contains(currentInput))
				{
					flag = true;
				}
				if (mod.package.inputs == currentInput)
				{
					if (Time.time < mod.package.timeout)
					{
						ClearEvent();
						break;
					}
					selected = mod.package;
					((Renderer)ballGlow).sharedMaterial = ballGlowMats[(int)mod.package.deployColor];
					((Renderer)beam).sharedMaterial = ballBeamMats[(int)mod.package.deployColor];
					((Renderer)lightGlow).sharedMaterial = ballLightMats[(int)mod.package.deployColor];
					((Component)ballGlow).gameObject.SetActive(true);
					SM.PlayCoreSound((FVRPooledAudioType)20, AudEvent_Ready, ((Component)this).transform.position);
					return;
				}
			}
			if (currentInput.Length >= 10 || !flag)
			{
				ClearEvent();
			}
			else
			{
				SM.PlayCoreSound((FVRPooledAudioType)20, AudEvent_Arrow, ((Component)this).transform.position);
			}
		}

		public override void BeginInteraction(FVRViveHand hand)
		{
			((FVRPhysicalObject)this).BeginInteraction(hand);
			if (!inputUI.activeSelf)
			{
				inputUI.SetActive(true);
				stratagemsUI.SetActive(true);
			}
		}

		public override void EndInteraction(FVRViveHand hand)
		{
			((FVRPhysicalObject)this).EndInteraction(hand);
			ClearMenu();
		}

		public override void SetQuickBeltSlot(FVRQuickBeltSlot slot)
		{
			((FVRPhysicalObject)this).SetQuickBeltSlot(slot);
			ClearMenu();
		}

		private void ClearMenu()
		{
			inputUI.SetActive(false);
			stratagemsUI.SetActive(false);
			if ((Object)(object)selected == (Object)null)
			{
				ClearEvent(silent: true);
			}
		}

		public override void EndInteractionIntoInventorySlot(FVRViveHand hand, FVRQuickBeltSlot slot)
		{
			((FVRPhysicalObject)this).EndInteractionIntoInventorySlot(hand, slot);
			ClearMenu();
		}

		public override void OnCollisionEnter(Collision col)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			((FVRPhysicalObject)this).OnCollisionEnter(col);
			if (((FVRInteractiveObject)this).IsHeld || !((Object)(object)((FVRPhysicalObject)this).QuickbeltSlot == (Object)null) || !((Object)(object)selected != (Object)null) || callingIn)
			{
				return;
			}
			callingIn = true;
			((Graphic)callTitle).color = textColors[(int)selected.textColor];
			callTitle.text = selected.title;
			((Graphic)callArrow).color = textColors[(int)selected.textColor];
			callThumbnail.sprite = selected.icon;
			((FVRPhysicalObject)this).RootRigidbody.velocity = Vector3.zero;
			((FVRPhysicalObject)this).RootRigidbody.angularVelocity = Vector3.zero;
			((FVRPhysicalObject)this).RootRigidbody.MoveRotation(Quaternion.identity);
			((FVRPhysicalObject)this).RootRigidbody.isKinematic = true;
			((FVRPhysicalObject)this).RootRigidbody.detectCollisions = false;
			parentTarget = col.transform;
			offset = ((Component)this).transform.position - col.transform.position;
			selected.timeout = Time.time + selected.cooldown;
			deployTimer = selected.deployTimer;
			((Component)callIn).gameObject.SetActive(true);
			((Component)ballGlow).gameObject.SetActive(false);
			((Component)beam).gameObject.SetActive(true);
			((Component)lightGlow).gameObject.SetActive(true);
			base.IsPickUpLocked = true;
			base.DistantGrabbable = false;
			ballAnimator.Play("Stratagem_Open", 0);
			if (selected.deployType == Stratagem_Package.DeployType.Hellpod)
			{
				NavMeshHit val = default(NavMeshHit);
				if (NavMesh.SamplePosition(((Component)this).transform.position, ref val, 2f, -1))
				{
					((FVRPhysicalObject)this).RootRigidbody.MovePosition(((NavMeshHit)(ref val)).position);
				}
				hellpod.SetActive(true);
				hellpod.transform.localPosition = Vector3.up * deployHeight;
				hellpodLandingEffect.SetActive(true);
				hellpodFlame.SetActive(true);
				SM.PlayCoreSound((FVRPooledAudioType)11, AudEvent_HellpodDrop, ((Component)this).transform.position);
			}
			SM.PlayCoreSound((FVRPooledAudioType)11, AudEvent_Beacon, ((Component)this).transform.position);
			SpawnInstantPrefabs();
			((MonoBehaviour)this).StartCoroutine(SelfDestruct(deployTimer));
		}

		public IEnumerator SelfDestruct(float timer)
		{
			yield return (object)new WaitForSeconds(timer);
			if (selected.deployType == Stratagem_Package.DeployType.Hellpod)
			{
				ShakeScreen();
				if (selected.deployType == Stratagem_Package.DeployType.Hellpod)
				{
					hellpod.transform.SetParent((Transform)null, true);
					hellpod.transform.position = ((Component)this).transform.position;
					StratagemPlugin.DestroyObject(300f, hellpod);
				}
				SM.PlayCoreSound((FVRPooledAudioType)11, hellpodLand, ((Component)this).transform.position);
				hellpodFlame.SetActive(false);
				hellpodLandedEffect.SetActive(true);
				((Component)callIn).gameObject.SetActive(false);
			}
			SpawnPrefabs();
			SpawnSosigs();
			SpawnObjectIDs();
			yield return (object)new WaitForSeconds(1f);
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}

		private void ShakeScreen()
		{
			//IL_000d: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			float num = 10f;
			float num2 = Vector3.Distance(((Component)this).transform.position, GM.CurrentPlayerBody.Head.position);
			float num3 = 1f;
			if (num2 < num)
			{
				num3 = 0f;
			}
			else if (num2 < num * 3f)
			{
				num3 = (num2 - num) / (num * 2f);
			}
			if (num3 < 1f)
			{
				SM.PowerSound(num3);
				float num4 = Mathf.Clamp(1f - num3, 0f, 1f);
				ScreenShake.TriggerShake(new ShakeProfile(3.5f * num4, 0.4f), new VignetteProfile(3.4f * num4, 1f, 0.35f, Color.black));
			}
		}

		public void ClearEvent(bool silent = false)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			currentInput = "";
			for (int i = 0; i < arrowInputs.Length; i++)
			{
				((Component)arrowInputs[i]).gameObject.SetActive(false);
			}
			if (!silent)
			{
				SM.PlayCoreSound((FVRPooledAudioType)20, AudEvent_Rattle, ((Component)this).transform.position);
			}
		}
	}
	[CreateAssetMenu(fileName = "Stratagem", menuName = "Stratagem/New Stratagem", order = 1)]
	public class Stratagem_Package : ScriptableObject
	{
		public enum DeployType
		{
			Instant,
			Hellpod
		}

		public enum DeployColor
		{
			Blue,
			Red
		}

		public enum TextColor
		{
			Yellow,
			Red,
			Blue,
			Green
		}

		[Tooltip("Name of the package, should match the Assets/FOLDERNAME")]
		public string packageName;

		[Tooltip("Name of the stratagem")]
		public string title;

		[Tooltip("Short description of what this stratagem does")]
		[Multiline(2)]
		public string description;

		public Sprite icon;

		[Tooltip("The input combination to spawn this stratagem \nU - Up\nD - Down\nL - Left\nR - Right")]
		public string inputs = "UDLR";

		[Tooltip("Instant = Instantly spawns all spawn items")]
		public DeployType deployType = DeployType.Instant;

		[Tooltip("How long before this deploys the spawns, set to 0 for Hellpods")]
		public float deployTimer = 5f;

		[Tooltip("Time between each use of this stratagem")]
		public float cooldown = 20f;

		[Tooltip("The color of the stratagem ball and beam")]
		public DeployColor deployColor = DeployColor.Blue;

		[Tooltip("The color of the type of stratagem, \nRed = Strike\nYellow = Emplacement/Supply")]
		public TextColor textColor = TextColor.Yellow;

		[HideInInspector]
		[Tooltip("The time stamp this stratagem can be used again")]
		public float timeout = 0f;

		[Header("Spawn")]
		[Tooltip("GameObjects that will spawn as soon as the Grenade activates")]
		public GameObject[] spawnInstantPrefab;

		[Tooltip("GameObjects that will spawn as soon as the deploy type has triggered")]
		public GameObject[] spawnPrefabs;

		[Tooltip("All Object IDs that will spawn when the deploy type has triggered")]
		public string[] spawnObjectIDs;

		[Tooltip("All spawn Object IDs will attempt to fit into any free slots on this backpack")]
		public string spawnBackpackID;

		[Tooltip("All Sosigs that will spawn when the deploy type has triggered")]
		public int[] spawnSosigEnemyIDs;
	}
	public class Stratagem_Preview : FVRPointable
	{
		[Header("Top Layer")]
		public GameObject topLayer;

		public Text title;

		public Image icon;

		public Image[] arrows;

		public GameObject arrowsParent;

		[Header("Description Layer")]
		public GameObject descriptionLayer;

		public Text description;

		[Header("Cooldown Layer")]
		public Text cooldown;

		[HideInInspector]
		public Stratagem_Package package;

		public override void OnPoint(FVRViveHand hand)
		{
			((FVRPointable)this).OnPoint(hand);
			topLayer.SetActive(false);
			descriptionLayer.SetActive(true);
		}

		public override void EndPoint(FVRViveHand hand)
		{
			((FVRPointable)this).EndPoint(hand);
			topLayer.SetActive(true);
			descriptionLayer.SetActive(false);
		}
	}
}
namespace Stratagem.src.Editor
{
	internal class Stratagem_Package_Drawer
	{
	}
}