Decompiled source of XSplitScreen v4.0.8

XSplitScreen.dll

Decompiled 2 weeks ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dodad.XSplitscreen.Components;
using HarmonyLib;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using Newtonsoft.Json;
using R2API;
using R2API.Utils;
using Rewired;
using Rewired.Data;
using RoR2;
using RoR2.ConVar;
using RoR2.EntitlementManagement;
using RoR2.ExpansionManagement;
using RoR2.Networking;
using RoR2.UI;
using RoR2.UI.MainMenu;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("XSplitScreen")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1+67f1de352ac6286dcf07802e8218486de281b459")]
[assembly: AssemblyProduct("XSplitScreen")]
[assembly: AssemblyTitle("XSplitScreen")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.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;
		}
	}
}
[RequireComponent(typeof(RectTransform))]
public class UISquare : Graphic
{
	[Min(0f)]
	public float thickness = 2f;

	public Color outlineColor = Color.black;

	public void Redraw()
	{
		((Graphic)this).SetVerticesDirty();
	}

	public override void OnRectTransformDimensionsChange()
	{
		((Graphic)this).OnRectTransformDimensionsChange();
		Redraw();
	}

	public override void OnPopulateMesh(VertexHelper vh)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_009b: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: 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_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: 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)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		vh.Clear();
		Rect rect = ((Graphic)this).rectTransform.rect;
		float xMin = ((Rect)(ref rect)).xMin;
		float xMax = ((Rect)(ref rect)).xMax;
		float yMax = ((Rect)(ref rect)).yMax;
		float yMin = ((Rect)(ref rect)).yMin;
		float num = Mathf.Clamp(thickness, 0f, Mathf.Min(((Rect)(ref rect)).width, ((Rect)(ref rect)).height) / 2f);
		Vector2[] array = (Vector2[])(object)new Vector2[4]
		{
			new Vector2(xMin, yMin),
			new Vector2(xMin, yMax),
			new Vector2(xMax, yMax),
			new Vector2(xMax, yMin)
		};
		Vector2[] array2 = (Vector2[])(object)new Vector2[4]
		{
			new Vector2(xMin + num, yMin + num),
			new Vector2(xMin + num, yMax - num),
			new Vector2(xMax - num, yMax - num),
			new Vector2(xMax - num, yMin + num)
		};
		UIVertex simpleVert = UIVertex.simpleVert;
		simpleVert.color = Color32.op_Implicit(outlineColor);
		for (int i = 0; i < 4; i++)
		{
			simpleVert.position = Vector2.op_Implicit(array[i]);
			vh.AddVert(simpleVert);
		}
		simpleVert.color = Color32.op_Implicit(((Graphic)this).color);
		for (int j = 0; j < 4; j++)
		{
			simpleVert.position = Vector2.op_Implicit(array2[j]);
			vh.AddVert(simpleVert);
		}
		for (int k = 0; k < 4; k++)
		{
			int num2 = (k + 1) % 4;
			vh.AddTriangle(k, num2, 4 + num2);
			vh.AddTriangle(k, 4 + num2, 4 + k);
		}
	}
}
[Serializable]
public class MultiDictionary : SerializableDictionary<string, StringDictionary>
{
}
[Serializable]
public class StringDictionary : SerializableDictionary<string, string>
{
}
[Serializable]
public class IntDictionary : SerializableDictionary<int, string>
{
}
[Serializable]
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, ISerializationCallbackReceiver
{
	[SerializeField]
	private List<TKey> keys = new List<TKey>();

	[SerializeField]
	private List<TValue> values = new List<TValue>();

	public void OnBeforeSerialize()
	{
		keys.Clear();
		values.Clear();
		using Enumerator enumerator = GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<TKey, TValue> current = enumerator.Current;
			keys.Add(current.Key);
			values.Add(current.Value);
		}
	}

	public void OnAfterDeserialize()
	{
		Clear();
		if (keys.Count != values.Count)
		{
			throw new Exception(string.Format("There are {0} keys and {1} values after deserialization. Make sure that both key and value types are serializable."));
		}
		for (int i = 0; i < keys.Count; i++)
		{
			Add(keys[i], values[i]);
		}
	}
}
namespace DoDad.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("XSplitScreen.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal Resources()
		{
		}
	}
}
namespace Dodad.XSplitscreen
{
	public class Graph
	{
		public class Face
		{
			public Rect Rect;

			public int GridRow;

			public int GridCol;

			public float WidthWeight = 1f;

			public float HeightWeight = 1f;

			public int Index { get; private set; }

			public Face(int index, int gridRow = 0, int gridCol = 0)
			{
				Index = index;
				GridRow = gridRow;
				GridCol = gridCol;
			}
		}

		private readonly float size;

		private Dictionary<int, Face> faces = new Dictionary<int, Face>();

		private int nextFaceIndex = 0;

		private List<List<int>> grid = new List<List<int>>();

		private List<float> colWeights = new List<float>();

		private List<float> rowWeights = new List<float>();

		public IReadOnlyDictionary<int, Face> Faces => faces;

		public Graph(float size = 1f)
		{
			this.size = size;
		}

		public int AddInitialFace()
		{
			Face face = new Face(nextFaceIndex++);
			faces.Add(face.Index, face);
			grid.Clear();
			grid.Add(new List<int> { face.Index });
			colWeights.Clear();
			colWeights.Add(1f);
			rowWeights.Clear();
			rowWeights.Add(1f);
			RecalculateRects();
			return face.Index;
		}

		public int InsertFromEdge(string edge)
		{
			string text = edge.ToLower();
			int count = grid.Count;
			int num = ((grid.Count > 0) ? grid[0].Count : 0);
			if (faces.Count == 0)
			{
				throw new InvalidOperationException("No faces in graph.");
			}
			int num2 = nextFaceIndex++;
			switch (text)
			{
			case "bottom":
			{
				List<int> list = new List<int>();
				for (int j = 0; j < num; j++)
				{
					list.Add(num2);
				}
				Face value2 = new Face(num2);
				faces.Add(num2, value2);
				grid.Insert(0, list);
				float item2 = ((rowWeights.Count > 0) ? rowWeights.Average() : 1f);
				rowWeights.Insert(0, item2);
				break;
			}
			case "top":
			{
				List<int> list2 = new List<int>();
				for (int l = 0; l < num; l++)
				{
					list2.Add(num2);
				}
				Face value4 = new Face(num2, grid.Count);
				faces.Add(num2, value4);
				grid.Add(list2);
				float item4 = ((rowWeights.Count > 0) ? rowWeights.Average() : 1f);
				rowWeights.Add(item4);
				break;
			}
			case "left":
			{
				for (int k = 0; k < count; k++)
				{
					grid[k].Insert(0, num2);
				}
				Face value3 = new Face(num2);
				faces.Add(num2, value3);
				float item3 = ((colWeights.Count > 0) ? colWeights.Average() : 1f);
				colWeights.Insert(0, item3);
				break;
			}
			case "right":
			{
				for (int i = 0; i < count; i++)
				{
					grid[i].Add(num2);
				}
				Face value = new Face(num2, 0, num);
				faces.Add(num2, value);
				float item = ((colWeights.Count > 0) ? colWeights.Average() : 1f);
				colWeights.Add(item);
				break;
			}
			default:
				throw new ArgumentException("Edge must be left, right, top, or bottom.");
			}
			RecalculateRects();
			return num2;
		}

		public (int, int) Subdivide(int faceIdx, bool vertical)
		{
			if (!faces.TryGetValue(faceIdx, out var _))
			{
				throw new ArgumentException($"Face index {faceIdx} not found.");
			}
			int num = nextFaceIndex++;
			List<(int, int)> faceCells = GetFaceCells(faceIdx);
			if (faceCells.Count == 0)
			{
				throw new InvalidOperationException($"Face {faceIdx} not found in grid");
			}
			Face value2 = new Face(num);
			faces.Add(num, value2);
			if (vertical)
			{
				List<int> list = (from c in faceCells.Select<(int, int), int>(((int row, int col) cell) => cell.col).Distinct()
					orderby c
					select c).ToList();
				if (list.Count < 2)
				{
					int num2 = list[0];
					float num3 = colWeights[num2];
					List<int> list2 = (from r in faceCells.Select<(int, int), int>(((int row, int col) cell) => cell.row).Distinct()
						orderby r
						select r).ToList();
					colWeights[num2] = num3 / 2f;
					colWeights.Insert(num2 + 1, num3 / 2f);
					for (int i = 0; i < grid.Count; i++)
					{
						if (list2.Contains(i))
						{
							grid[i].Insert(num2 + 1, num);
							continue;
						}
						int item = grid[i][num2];
						grid[i].Insert(num2 + 1, item);
					}
				}
				else
				{
					int index = list.Count / 2;
					int num4 = list[index];
					foreach (var item3 in faceCells)
					{
						if (item3.Item2 >= num4)
						{
							grid[item3.Item1][item3.Item2] = num;
						}
					}
				}
			}
			else
			{
				List<int> list3 = (from r in faceCells.Select<(int, int), int>(((int row, int col) cell) => cell.row).Distinct()
					orderby r
					select r).ToList();
				if (list3.Count < 2)
				{
					int num5 = list3[0];
					float num6 = rowWeights[num5];
					List<int> list4 = (from c in faceCells.Select<(int, int), int>(((int row, int col) cell) => cell.col).Distinct()
						orderby c
						select c).ToList();
					rowWeights[num5] = num6 / 2f;
					List<int> list5 = new List<int>();
					for (int j = 0; j < grid[num5].Count; j++)
					{
						if (list4.Contains(j))
						{
							list5.Add(num);
							continue;
						}
						int item2 = grid[num5][j];
						list5.Add(item2);
					}
					grid.Insert(num5 + 1, list5);
					rowWeights.Insert(num5 + 1, num6 / 2f);
				}
				else
				{
					int index2 = list3.Count / 2;
					int num7 = list3[index2];
					foreach (var item4 in faceCells)
					{
						if (item4.Item1 >= num7)
						{
							grid[item4.Item1][item4.Item2] = num;
						}
					}
				}
			}
			RecalculateRects();
			return (faceIdx, num);
		}

		public void RemoveFace(int faceIdx)
		{
			if (!faces.ContainsKey(faceIdx))
			{
				return;
			}
			List<(int, int)> faceCells = GetFaceCells(faceIdx);
			if (faceCells.Count != 0)
			{
				Dictionary<int, HashSet<(int, int)>> dictionary = FindNeighborCells(faceIdx, faceCells);
				if (dictionary.Count == 0)
				{
					faces.Remove(faceIdx);
					CleanupGridAfterFaceRemoval(faceCells);
					RecalculateRects();
					return;
				}
				Dictionary<int, List<(int, int, int, int)>> neighborRectangles = CalculateExpandableRectangles(dictionary, faceCells);
				ApplyRectangularReplacements(faceIdx, faceCells, neighborRectangles);
				faces.Remove(faceIdx);
				OptimizeGrid();
				ValidateGrid();
				RecalculateRects();
			}
		}

		private Dictionary<int, HashSet<(int row, int col)>> FindNeighborCells(int faceIdx, List<(int row, int col)> faceCells)
		{
			Dictionary<int, HashSet<(int, int)>> dictionary = new Dictionary<int, HashSet<(int, int)>>();
			int[][] array = new int[4][]
			{
				new int[2] { -1, 0 },
				new int[2] { 0, 1 },
				new int[2] { 1, 0 },
				new int[2] { 0, -1 }
			};
			foreach (var faceCell in faceCells)
			{
				int[][] array2 = array;
				foreach (int[] array3 in array2)
				{
					int num = faceCell.row + array3[0];
					int num2 = faceCell.col + array3[1];
					if (num < 0 || num >= grid.Count || num2 < 0 || num2 >= grid[num].Count)
					{
						continue;
					}
					int num3 = grid[num][num2];
					if (num3 != faceIdx && faces.ContainsKey(num3))
					{
						if (!dictionary.ContainsKey(num3))
						{
							dictionary[num3] = new HashSet<(int, int)>();
						}
						dictionary[num3].Add((num, num2));
					}
				}
			}
			return dictionary;
		}

		private Dictionary<int, List<(int minRow, int maxRow, int minCol, int maxCol)>> CalculateExpandableRectangles(Dictionary<int, HashSet<(int row, int col)>> neighborCells, List<(int row, int col)> removedCells)
		{
			Dictionary<int, List<(int, int, int, int)>> dictionary = new Dictionary<int, List<(int, int, int, int)>>();
			HashSet<(int, int)> removedCells2 = new HashSet<(int, int)>(removedCells);
			foreach (KeyValuePair<int, HashSet<(int, int)>> neighborCell in neighborCells)
			{
				int key = neighborCell.Key;
				HashSet<(int, int)> value = neighborCell.Value;
				List<(int, int)> faceCells = GetFaceCells(key);
				int minRow = faceCells.Min<(int, int)>(((int row, int col) c) => c.row);
				int maxRow = faceCells.Max<(int, int)>(((int row, int col) c) => c.row);
				int minCol = faceCells.Min<(int, int)>(((int row, int col) c) => c.col);
				int maxCol = faceCells.Max<(int, int)>(((int row, int col) c) => c.col);
				dictionary[key] = CalculatePotentialRectangles(minRow, maxRow, minCol, maxCol, faceCells, removedCells2);
			}
			return dictionary;
		}

		private List<(int minRow, int maxRow, int minCol, int maxCol)> CalculatePotentialRectangles(int minRow, int maxRow, int minCol, int maxCol, List<(int row, int col)> faceCells, HashSet<(int row, int col)> removedCells)
		{
			List<(int, int, int, int)> list = new List<(int, int, int, int)>();
			for (int i = maxCol + 1; CanExpandToCol(minRow, maxRow, i, faceCells, removedCells); i++)
			{
				list.Add((minRow, maxRow, minCol, i));
			}
			int num = minCol - 1;
			while (num >= 0 && CanExpandToCol(minRow, maxRow, num, faceCells, removedCells))
			{
				list.Add((minRow, maxRow, num, maxCol));
				num--;
			}
			for (int j = maxRow + 1; CanExpandToRow(minCol, maxCol, j, faceCells, removedCells); j++)
			{
				list.Add((minRow, j, minCol, maxCol));
			}
			int num2 = minRow - 1;
			while (num2 >= 0 && CanExpandToRow(minCol, maxCol, num2, faceCells, removedCells))
			{
				list.Add((num2, maxRow, minCol, maxCol));
				num2--;
			}
			return list;
		}

		private bool CanExpandToCol(int minRow, int maxRow, int col, List<(int row, int col)> faceCells, HashSet<(int row, int col)> removedCells)
		{
			if (col < 0 || col >= grid[0].Count)
			{
				return false;
			}
			for (int i = minRow; i <= maxRow; i++)
			{
				if (!removedCells.Contains((i, col)) && !faceCells.Contains((i, col)))
				{
					return false;
				}
			}
			return true;
		}

		private bool CanExpandToRow(int minCol, int maxCol, int row, List<(int row, int col)> faceCells, HashSet<(int row, int col)> removedCells)
		{
			if (row < 0 || row >= grid.Count)
			{
				return false;
			}
			for (int i = minCol; i <= maxCol; i++)
			{
				if (!removedCells.Contains((row, i)) && !faceCells.Contains((row, i)))
				{
					return false;
				}
			}
			return true;
		}

		private void ApplyRectangularReplacements(int faceIdx, List<(int row, int col)> removedCells, Dictionary<int, List<(int minRow, int maxRow, int minCol, int maxCol)>> neighborRectangles)
		{
			List<List<int>> list = new List<List<int>>(grid.Count);
			for (int i = 0; i < grid.Count; i++)
			{
				list.Add(new List<int>(grid[i]));
			}
			HashSet<(int, int)> hashSet = new HashSet<(int, int)>(removedCells);
			while (hashSet.Count > 0)
			{
				int num = -1;
				(int, int, int, int) tuple = (0, 0, 0, 0);
				int num2 = 0;
				foreach (KeyValuePair<int, List<(int, int, int, int)>> neighborRectangle in neighborRectangles)
				{
					int key = neighborRectangle.Key;
					foreach (var item in neighborRectangle.Value)
					{
						int num3 = CountCoveredCells(item.Item1, item.Item2, item.Item3, item.Item4, hashSet);
						if (num3 > num2)
						{
							num2 = num3;
							num = key;
							tuple = item;
						}
					}
				}
				if (num2 > 0)
				{
					var (j, _, _, _) = tuple;
					for (; j <= tuple.Item2; j++)
					{
						for (int k = tuple.Item3; k <= tuple.Item4; k++)
						{
							if (j < grid.Count && k < grid[j].Count && grid[j][k] == faceIdx)
							{
								grid[j][k] = num;
								hashSet.Remove((j, k));
							}
						}
					}
					if (neighborRectangles.ContainsKey(num))
					{
						List<(int, int)> faceCells = GetFaceCells(num);
						int minRow = faceCells.Min<(int, int)>(((int row, int col) c) => c.row);
						int maxRow = faceCells.Max<(int, int)>(((int row, int col) c) => c.row);
						int minCol = faceCells.Min<(int, int)>(((int row, int col) c) => c.col);
						int maxCol = faceCells.Max<(int, int)>(((int row, int col) c) => c.col);
						neighborRectangles[num] = CalculatePotentialRectangles(minRow, maxRow, minCol, maxCol, faceCells, hashSet);
					}
					continue;
				}
				int num4 = nextFaceIndex++;
				Face value = new Face(num4);
				faces.Add(num4, value);
				foreach (var item2 in hashSet)
				{
					grid[item2.Item1][item2.Item2] = num4;
				}
				hashSet.Clear();
			}
		}

		private int CountCoveredCells(int minRow, int maxRow, int minCol, int maxCol, HashSet<(int row, int col)> cells)
		{
			int num = 0;
			for (int i = minRow; i <= maxRow; i++)
			{
				for (int j = minCol; j <= maxCol; j++)
				{
					if (cells.Contains((i, j)))
					{
						num++;
					}
				}
			}
			return num;
		}

		private void ValidateGrid()
		{
			if (grid.Count == 0 || faces.Count == 0)
			{
				return;
			}
			int value = faces.Keys.First();
			for (int i = 0; i < grid.Count; i++)
			{
				for (int j = 0; j < grid[i].Count; j++)
				{
					int key = grid[i][j];
					if (!faces.ContainsKey(key))
					{
						grid[i][j] = value;
					}
				}
			}
		}

		private List<(int row, int col)> GetFaceCells(int faceIdx)
		{
			List<(int, int)> list = new List<(int, int)>();
			for (int i = 0; i < grid.Count; i++)
			{
				for (int j = 0; j < grid[i].Count; j++)
				{
					if (grid[i][j] == faceIdx)
					{
						list.Add((i, j));
					}
				}
			}
			return list;
		}

		private void CleanupGridAfterFaceRemoval(List<(int row, int col)> removedCells)
		{
			List<int> list = (from r in removedCells.Select(((int row, int col) cell) => cell.row).Distinct()
				orderby r descending
				select r).ToList();
			List<int> list2 = (from c in removedCells.Select(((int row, int col) cell) => cell.col).Distinct()
				orderby c descending
				select c).ToList();
			foreach (int item2 in list)
			{
				if (item2 >= grid.Count)
				{
					continue;
				}
				bool flag = true;
				for (int i = 0; i < grid[item2].Count; i++)
				{
					int key = grid[item2][i];
					if (faces.ContainsKey(key))
					{
						flag = false;
						break;
					}
				}
				if (flag && grid.Count > 1)
				{
					grid.RemoveAt(item2);
					if (item2 < rowWeights.Count)
					{
						rowWeights.RemoveAt(item2);
					}
				}
			}
			if (grid.Count > 0)
			{
				int num = grid[0].Count;
				foreach (int item3 in list2)
				{
					if (item3 >= num)
					{
						continue;
					}
					bool flag2 = true;
					for (int j = 0; j < grid.Count; j++)
					{
						if (item3 < grid[j].Count)
						{
							int key2 = grid[j][item3];
							if (faces.ContainsKey(key2))
							{
								flag2 = false;
								break;
							}
						}
					}
					if (!flag2 || num <= 1)
					{
						continue;
					}
					for (int k = 0; k < grid.Count; k++)
					{
						if (item3 < grid[k].Count)
						{
							grid[k].RemoveAt(item3);
						}
					}
					if (item3 < colWeights.Count)
					{
						colWeights.RemoveAt(item3);
					}
					num--;
				}
			}
			if ((grid.Count == 0 || grid[0].Count == 0) && faces.Count > 0)
			{
				int item = faces.Keys.First();
				grid.Clear();
				grid.Add(new List<int> { item });
				colWeights.Clear();
				colWeights.Add(1f);
				rowWeights.Clear();
				rowWeights.Add(1f);
			}
		}

		private void OptimizeGrid()
		{
			if (grid.Count == 0)
			{
				return;
			}
			for (int num = grid.Count - 2; num >= 0; num--)
			{
				if (grid[num].Count == grid[num + 1].Count)
				{
					bool flag = true;
					for (int i = 0; i < grid[num].Count; i++)
					{
						if (grid[num][i] != grid[num + 1][i])
						{
							flag = false;
							break;
						}
					}
					if (flag)
					{
						rowWeights[num] += rowWeights[num + 1];
						rowWeights.RemoveAt(num + 1);
						grid.RemoveAt(num + 1);
					}
				}
			}
			for (int num2 = grid[0].Count - 2; num2 >= 0; num2--)
			{
				bool flag2 = true;
				for (int j = 0; j < grid.Count; j++)
				{
					if (num2 + 1 >= grid[j].Count || grid[j][num2] != grid[j][num2 + 1])
					{
						flag2 = false;
						break;
					}
				}
				if (flag2)
				{
					colWeights[num2] += colWeights[num2 + 1];
					colWeights.RemoveAt(num2 + 1);
					for (int k = 0; k < grid.Count; k++)
					{
						grid[k].RemoveAt(num2 + 1);
					}
				}
			}
			EnsureFacesAreRectangular();
			NormalizeGrid();
		}

		private void EnsureFacesAreRectangular()
		{
			Dictionary<int, List<(int, int)>> dictionary = new Dictionary<int, List<(int, int)>>();
			for (int i = 0; i < grid.Count; i++)
			{
				for (int j = 0; j < grid[i].Count; j++)
				{
					int key = grid[i][j];
					if (!dictionary.ContainsKey(key))
					{
						dictionary[key] = new List<(int, int)>();
					}
					dictionary[key].Add((i, j));
				}
			}
			HashSet<int> hashSet = new HashSet<int>();
			foreach (KeyValuePair<int, List<(int, int)>> item in dictionary)
			{
				int key2 = item.Key;
				List<(int, int)> value = item.Value;
				if (!faces.ContainsKey(key2) || value.Count <= 1)
				{
					continue;
				}
				int num = int.MaxValue;
				int num2 = int.MinValue;
				int num3 = int.MaxValue;
				int num4 = int.MinValue;
				foreach (var item2 in value)
				{
					num = Math.Min(num, item2.Item1);
					num2 = Math.Max(num2, item2.Item1);
					num3 = Math.Min(num3, item2.Item2);
					num4 = Math.Max(num4, item2.Item2);
				}
				bool flag = true;
				for (int k = num; k <= num2; k++)
				{
					for (int l = num3; l <= num4; l++)
					{
						if (k < grid.Count && l < grid[k].Count && grid[k][l] != key2)
						{
							flag = false;
							hashSet.Add(key2);
							break;
						}
					}
					if (!flag)
					{
						break;
					}
				}
			}
			if (hashSet.Count <= 0)
			{
				return;
			}
			foreach (int item3 in hashSet)
			{
				if (!faces.ContainsKey(item3))
				{
					continue;
				}
				List<(int, int)> cells = dictionary[item3];
				List<List<(int, int)>> list = FindRectangularRegions(cells);
				for (int m = 1; m < list.Count; m++)
				{
					int num5 = nextFaceIndex++;
					Face value2 = new Face(num5);
					faces.Add(num5, value2);
					foreach (var item4 in list[m])
					{
						grid[item4.Item1][item4.Item2] = num5;
					}
				}
			}
		}

		private List<List<(int row, int col)>> FindRectangularRegions(List<(int row, int col)> cells)
		{
			List<List<(int, int)>> list = new List<List<(int, int)>>();
			HashSet<(int, int)> hashSet = new HashSet<(int, int)>(cells);
			while (hashSet.Count > 0)
			{
				(int, int) tuple = hashSet.First();
				int num = tuple.Item1;
				int num2 = tuple.Item1;
				int num3 = tuple.Item2;
				int num4 = tuple.Item2;
				bool flag;
				do
				{
					flag = false;
					if (CanExpandRectangle(num, num2, num3, num4 + 1, hashSet))
					{
						num4++;
						flag = true;
					}
					if (CanExpandRectangle(num, num2 + 1, num3, num4, hashSet))
					{
						num2++;
						flag = true;
					}
					if (CanExpandRectangle(num, num2, num3 - 1, num4, hashSet))
					{
						num3--;
						flag = true;
					}
					if (CanExpandRectangle(num - 1, num2, num3, num4, hashSet))
					{
						num--;
						flag = true;
					}
				}
				while (flag);
				List<(int, int)> list2 = new List<(int, int)>();
				for (int i = num; i <= num2; i++)
				{
					for (int j = num3; j <= num4; j++)
					{
						(int, int) item = (i, j);
						if (hashSet.Contains(item))
						{
							list2.Add(item);
							hashSet.Remove(item);
						}
					}
				}
				list.Add(list2);
			}
			return list;
		}

		private bool CanExpandRectangle(int minRow, int maxRow, int minCol, int maxCol, HashSet<(int row, int col)> cells)
		{
			for (int i = minRow; i <= maxRow; i++)
			{
				for (int j = minCol; j <= maxCol; j++)
				{
					if (!cells.Contains((i, j)))
					{
						return false;
					}
				}
			}
			return true;
		}

		private void NormalizeGrid()
		{
			if (grid.Count == 0)
			{
				return;
			}
			int num = 0;
			foreach (List<int> item in grid)
			{
				num = Mathf.Max(num, item.Count);
			}
			if (num == 0)
			{
				return;
			}
			for (int i = 0; i < grid.Count; i++)
			{
				while (grid[i].Count < num)
				{
					int num2 = ((grid[i].Count > 0) ? grid[i][grid[i].Count - 1] : (-1));
					if (num2 >= 0 && faces.ContainsKey(num2))
					{
						grid[i].Add(num2);
						continue;
					}
					if (grid[i].Count > 0)
					{
						grid[i].Add(grid[i][grid[i].Count - 1]);
						continue;
					}
					break;
				}
			}
			while (colWeights.Count < num)
			{
				colWeights.Add(1f);
			}
			while (colWeights.Count > num && num > 0)
			{
				colWeights.RemoveAt(colWeights.Count - 1);
			}
			while (rowWeights.Count < grid.Count)
			{
				rowWeights.Add(1f);
			}
			while (rowWeights.Count > grid.Count && grid.Count > 0)
			{
				rowWeights.RemoveAt(rowWeights.Count - 1);
			}
		}

		private void RecalculateRects()
		{
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			int count = grid.Count;
			int num = ((grid.Count > 0) ? grid[0].Count : 0);
			if (count == 0 || num == 0)
			{
				return;
			}
			float num2 = colWeights.Sum();
			float num3 = rowWeights.Sum();
			List<float> list = new List<float>();
			List<float> list2 = new List<float>();
			float num4 = 0f;
			for (int i = 0; i < num; i++)
			{
				float num5 = colWeights[i] / num2;
				list.Add(num4);
				float num6 = num5 * size;
				list2.Add(num6);
				num4 += num6;
			}
			List<float> list3 = new List<float>();
			List<float> list4 = new List<float>();
			float num7 = 0f;
			for (int j = 0; j < count; j++)
			{
				float num8 = rowWeights[j] / num3;
				list3.Add(num7);
				float num9 = num8 * size;
				list4.Add(num9);
				num7 += num9;
			}
			foreach (Face value in faces.Values)
			{
				value.Rect = new Rect(0f, 0f, 0f, 0f);
			}
			HashSet<int> hashSet = new HashSet<int>();
			Rect rect = default(Rect);
			for (int k = 0; k < count; k++)
			{
				for (int l = 0; l < num; l++)
				{
					int num10 = grid[k][l];
					if (num10 < 0 || !faces.ContainsKey(num10))
					{
						continue;
					}
					Face face = faces[num10];
					float num11 = list[l];
					float num12 = list3[k];
					float num13 = list2[l];
					float num14 = list4[k];
					((Rect)(ref rect))..ctor(num11, num12, num13, num14);
					if (!hashSet.Contains(num10))
					{
						face.GridRow = k;
						face.GridCol = l;
						face.Rect = rect;
						hashSet.Add(num10);
						continue;
					}
					float num15 = Mathf.Min(((Rect)(ref face.Rect)).x, ((Rect)(ref rect)).x);
					float num16 = Mathf.Min(((Rect)(ref face.Rect)).y, ((Rect)(ref rect)).y);
					float num17 = Mathf.Max(((Rect)(ref face.Rect)).x + ((Rect)(ref face.Rect)).width, ((Rect)(ref rect)).x + ((Rect)(ref rect)).width);
					float num18 = Mathf.Max(((Rect)(ref face.Rect)).y + ((Rect)(ref face.Rect)).height, ((Rect)(ref rect)).y + ((Rect)(ref rect)).height);
					face.Rect = new Rect(num15, num16, num17 - num15, num18 - num16);
					if (k < face.GridRow)
					{
						face.GridRow = k;
					}
					if (l < face.GridCol)
					{
						face.GridCol = l;
					}
				}
			}
		}

		public Face GetFace(int index)
		{
			faces.TryGetValue(index, out var value);
			return value;
		}

		public void Clear()
		{
			faces.Clear();
			grid.Clear();
			colWeights.Clear();
			rowWeights.Clear();
		}

		public void DebugPrintFaces()
		{
			Log.Print("Faces in graph:");
			foreach (Face value in faces.Values)
			{
				Log.Print($"Face {value.Index}: Rect=({((Rect)(ref value.Rect)).x}, {((Rect)(ref value.Rect)).y}, {((Rect)(ref value.Rect)).width}, {((Rect)(ref value.Rect)).height}) " + $"GridRow={value.GridRow} GridCol={value.GridCol}");
			}
			Log.Print("Grid layout:");
			for (int i = 0; i < grid.Count; i++)
			{
				string text = $"Row {i}: ";
				for (int j = 0; j < grid[i].Count; j++)
				{
					text += $"[{grid[i][j]}] ";
				}
				Log.Print(text);
			}
			Log.Print("Column weights: " + string.Join(", ", colWeights));
			Log.Print("Row weights: " + string.Join(", ", rowWeights));
			Log.Print(" -- End --");
		}
	}
	public static class HookManager
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Manipulator <0>__RunCameraManager_Update_IL;

			public static Action<ControllerStatusChangedEventArgs> <1>__OnControllerConnected;
		}

		private static MethodInfo RunCameraManager_Udpate_Orig;

		private static MethodInfo RunCameraManager_Udpate_Patch;

		private static ChatBox ChatInstance;

		private static MethodInfo ChatBox_Update_Orig;

		private static MethodInfo ChatBox_Update_Patch;

		private static MethodInfo PlayerCharacterMasterController_OnBodyStart_Orig;

		private static MethodInfo PlayerCharacterMasterController_OnBodyStart_Patch;

		private static MethodInfo CameraRigController_Start_Orig;

		private static MethodInfo CameraRigController_Start_Patch;

		private static MethodInfo MPEventSystem_OnLastActiveControllerChanged_Orig;

		private static MethodInfo MPEventSystem_OnLastActiveControllerChanged_Patch;

		private static MethodInfo PauseStopController_allowMultiplayerPause_Orig;

		private static MethodInfo PauseStopController_allowMultiplayerPause_Patch;

		public static void OnStateChange(bool state)
		{
			Log.Print($"HookManager::OnStateChange -> '{state}'");
			ResizePlayerCount(state);
			UpdateCameraRects(state);
			UpdateMultiplayerColors(state);
			UpdateDisplayHook(state);
			UpdateTrailHooks(state);
			UpdateMPEventHooks(state);
			UpdateChatHooks(state);
			UpdateSubscriptions(state);
			UpdateRunCameraManager(state);
			UpdatePauseScreenBehaviourHook(state);
		}

		private static void ResizePlayerCount(bool state)
		{
			int num = 4;
			if (state)
			{
				num = Math.Max(4, SplitscreenUserManager.LocalUsers.Count);
			}
			((BaseConVar)LobbyManager.cvSteamLobbyMaxMembers).defaultValue = num.ToString();
			Reflection.SetPropertyValue<int>((object)LobbyManager.cvSteamLobbyMaxMembers, "value", num);
			((BaseConVar)SvMaxPlayersConVar.instance).SetString(num.ToString());
		}

		private static void UpdateRunCameraManager(bool isSplitscreenEnabled)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (isSplitscreenEnabled)
			{
				object obj = <>O.<0>__RunCameraManager_Update_IL;
				if (obj == null)
				{
					Manipulator val = RunCameraManager_Update_IL;
					<>O.<0>__RunCameraManager_Update_IL = val;
					obj = (object)val;
				}
				RunCameraManager.Update += (Manipulator)obj;
			}
			else
			{
				object obj2 = <>O.<0>__RunCameraManager_Update_IL;
				if (obj2 == null)
				{
					Manipulator val2 = RunCameraManager_Update_IL;
					<>O.<0>__RunCameraManager_Update_IL = val2;
					obj2 = (object)val2;
				}
				RunCameraManager.Update -= (Manipulator)obj2;
			}
		}

		public static void LogInputPlayerName(string name)
		{
			Log.Print("HookManager::LogInputPlayerName: '" + name + "'");
		}

		private static void RunCameraManager_Update_IL(ILContext il)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00d6: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: 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_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext(new Func<Instruction, bool>[5]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 16),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<LocalUser>(x, "get_inputPlayer"),
				(Instruction x) => ILPatternMatchingExt.MatchCallvirt<Player>(x, "get_name"),
				(Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "PlayerMain"),
				(Instruction x) => ILPatternMatchingExt.MatchCall<string>(x, "op_Equality")
			}))
			{
				val.Index += 3;
				val.Emit(OpCodes.Dup);
				val.Emit(OpCodes.Stloc_S, (byte)18);
				string[] array = new string[4] { "PlayerMain", "Player2", "Player3", "Player4" };
				MethodInfo method = typeof(string).GetMethod("op_Equality", new Type[2]
				{
					typeof(string),
					typeof(string)
				});
				ILLabel val2 = val.DefineLabel();
				string[] array2 = array;
				foreach (string text in array2)
				{
					val.Emit(OpCodes.Dup);
					val.Emit(OpCodes.Ldstr, text);
					val.Emit(OpCodes.Call, (MethodBase)method);
					val.Emit(OpCodes.Brtrue_S, (object)val2);
				}
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldfld, typeof(RunCameraManager).GetField("CharacterSelectUILocal"));
				val.Emit(OpCodes.Call, (MethodBase)typeof(Object).GetMethod("Instantiate", new Type[1] { typeof(GameObject) }));
				val.Emit(OpCodes.Stloc_S, (byte)17);
				val.Emit(OpCodes.Ldloc_S, (byte)17);
				MethodInfo methodInfo = typeof(GameObject).GetMethods().First((MethodInfo m) => m.Name == "GetComponent" && m.IsGenericMethod && m.GetGenericArguments().Length == 1 && m.GetParameters().Length == 0).MakeGenericMethod(typeof(MPEventSystemProvider));
				val.Emit(OpCodes.Callvirt, (MethodBase)methodInfo);
				val.Emit(OpCodes.Ldloc_S, (byte)18);
				MethodInfo method2 = typeof(LocalUserManager).GetMethod("FindLocalUserByPlayerName", new Type[1] { typeof(string) });
				val.Emit(OpCodes.Call, (MethodBase)method2);
				val.Emit(OpCodes.Dup);
				ILLabel val3 = val.DefineLabel();
				val.Emit(OpCodes.Brtrue_S, (object)val3);
				val.Emit(OpCodes.Pop);
				val.Emit(OpCodes.Ldnull);
				ILLabel val4 = val.DefineLabel();
				val.Emit(OpCodes.Br_S, (object)val4);
				val.MarkLabel(val3);
				MethodInfo getMethod = typeof(LocalUser).GetProperty("inputPlayer").GetGetMethod();
				val.Emit(OpCodes.Callvirt, (MethodBase)getMethod);
				val.MarkLabel(val4);
				MethodInfo method3 = typeof(MPEventSystem).GetMethod("FindByPlayer", new Type[1] { typeof(Player) });
				val.Emit(OpCodes.Call, (MethodBase)method3);
				MethodInfo setMethod = typeof(MPEventSystemProvider).GetProperty("eventSystem").GetSetMethod();
				val.Emit(OpCodes.Callvirt, (MethodBase)setMethod);
				ILLabel val5 = val.DefineLabel();
				val.Emit(OpCodes.Br_S, (object)val5);
				val.MarkLabel(val2);
				val.MarkLabel(val5);
			}
			else
			{
				Log.Print("Could not hook '" + ((MemberReference)il.Method).Name + "'", Log.ELogChannel.Error);
			}
		}

		private static void UpdateChatHooks(bool isSplitscreenEnabled)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if ((object)ChatBox_Update_Orig == null)
			{
				ChatBox_Update_Orig = typeof(ChatBox).GetMethod("Update", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)ChatBox_Update_Patch == null)
			{
				ChatBox_Update_Patch = typeof(HookManager).GetMethod("ChatBox_Update", BindingFlags.Static | BindingFlags.NonPublic);
			}
			if (isSplitscreenEnabled)
			{
				Plugin.Patcher.Patch((MethodBase)ChatBox_Update_Orig, new HarmonyMethod(ChatBox_Update_Patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Patcher.Unpatch((MethodBase)ChatBox_Update_Orig, ChatBox_Update_Patch);
			}
		}

		private static bool ChatBox_Update(ChatBox __instance)
		{
			if ((Object)(object)ChatInstance == (Object)null)
			{
				ChatInstance = __instance;
			}
			if ((Object)(object)ChatInstance != (Object)(object)__instance)
			{
				return false;
			}
			return true;
		}

		private static void UpdateTrailHooks(bool isSplitscreenEnabled)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if ((object)PlayerCharacterMasterController_OnBodyStart_Orig == null)
			{
				PlayerCharacterMasterController_OnBodyStart_Orig = typeof(PlayerCharacterMasterController).GetMethod("SetBody", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)PlayerCharacterMasterController_OnBodyStart_Patch == null)
			{
				PlayerCharacterMasterController_OnBodyStart_Patch = typeof(HookManager).GetMethod("PlayerCharacterMasterController_SetBody", BindingFlags.Static | BindingFlags.NonPublic);
			}
			if (isSplitscreenEnabled)
			{
				Plugin.Patcher.Patch((MethodBase)PlayerCharacterMasterController_OnBodyStart_Orig, (HarmonyMethod)null, new HarmonyMethod(PlayerCharacterMasterController_OnBodyStart_Patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Patcher.Unpatch((MethodBase)PlayerCharacterMasterController_OnBodyStart_Orig, PlayerCharacterMasterController_OnBodyStart_Patch);
			}
		}

		private static void PlayerCharacterMasterController_SetBody(PlayerCharacterMasterController __instance, GameObject __0)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__0 == (Object)null || !((Object)(object)__instance.networkUser != (Object)null) || !((NetworkBehaviour)__instance.networkUser).isLocalPlayer || __instance.networkUser.localUser == null)
			{
				return;
			}
			LocalUser userByInputName = SplitscreenUserManager.GetUserByInputName(__instance.networkUser.localUser.inputPlayer.name);
			if (!((Object)(object)userByInputName.ParticleSystem != (Object)null) && __instance.networkUser.localUser.userProfile.fileName != null)
			{
				string trailKey = SplitScreenSettings.GetOrCreateUserModule<TrailsSettingsModule>(__instance.networkUser.localUser.userProfile.fileName).TrailKey;
				if (trailKey == "none")
				{
					userByInputName.ParticleSystem = new GameObject("Dummy").transform;
					return;
				}
				Transform particleSystem = ParticleSystemFactory.GetParticleSystem(trailKey);
				((Component)particleSystem).transform.SetParent(__instance.body.transform);
				((Component)particleSystem).transform.localPosition = Vector3.zero;
				((Component)particleSystem).gameObject.SetActive(true);
				userByInputName.ParticleSystem = ((Component)particleSystem).transform;
			}
		}

		private static void UpdateMultiplayerColors(bool isSplitscreenEnabled)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			Color[] array = (Color[])(object)new Color[4]
			{
				Color32.op_Implicit(new Color32((byte)252, (byte)62, (byte)62, byte.MaxValue)),
				Color32.op_Implicit(new Color32((byte)62, (byte)109, (byte)252, byte.MaxValue)),
				Color32.op_Implicit(new Color32((byte)129, (byte)252, (byte)62, byte.MaxValue)),
				Color32.op_Implicit(new Color32((byte)252, (byte)241, (byte)62, byte.MaxValue))
			};
			if (isSplitscreenEnabled)
			{
				IReadOnlyList<LocalUser> localUsers = SplitscreenUserManager.LocalUsers;
				array = (Color[])(object)new Color[localUsers.Count];
				for (int i = 0; i < localUsers.Count; i++)
				{
					array[i] = SplitScreenSettings.GetUserModule<ColorSettingsModule>(localUsers[i].Profile?.fileName ?? string.Empty)?.Color ?? Color.white;
				}
			}
			Plugin.UpdateMultiplayerColors(array);
		}

		private static void UpdateDisplayHook(bool isSplitscreenEnabled)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if ((object)CameraRigController_Start_Orig == null)
			{
				CameraRigController_Start_Orig = typeof(CameraRigController).GetMethod("Start", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)CameraRigController_Start_Patch == null)
			{
				CameraRigController_Start_Patch = typeof(HookManager).GetMethod("CameraRigController_Start", BindingFlags.Static | BindingFlags.NonPublic);
			}
			if (isSplitscreenEnabled)
			{
				Plugin.Patcher.Patch((MethodBase)CameraRigController_Start_Orig, (HarmonyMethod)null, new HarmonyMethod(CameraRigController_Start_Patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Patcher.Unpatch((MethodBase)CameraRigController_Start_Orig, CameraRigController_Start_Patch);
			}
		}

		private static void CameraRigController_Start(CameraRigController __instance)
		{
			ExecuteNextFrame.Invoke(delegate
			{
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)RunCameraManager.instance == (Object)null))
				{
					FieldInfo field = typeof(RunCameraManager).GetField("cameras", BindingFlags.Instance | BindingFlags.NonPublic);
					Dictionary<string, CameraRigController> dictionary = (Dictionary<string, CameraRigController>)field.GetValue(RunCameraManager.instance);
					string text = null;
					foreach (KeyValuePair<string, CameraRigController> item in dictionary)
					{
						Log.Print("CameraRigController_Start: kvp -> '" + item.Key + "'");
						if ((Object)(object)item.Value == (Object)(object)__instance)
						{
							Log.Print("CameraRigController_Start: '" + item.Key + "' accepted");
							text = item.Key;
							break;
						}
					}
					if (text != null)
					{
						int display = SplitscreenUserManager.GetUserByInputName(text).Display;
						Log.Print($"CameraRigController_Start: User '{text}' on display '{display}'");
						Log.Print($"Null -> sceneCam = '{(Object)(object)__instance.sceneCam == (Object)null}', uiCam = '{(Object)(object)__instance.uiCam == (Object)null}', skyboxCam = '{(Object)(object)__instance.skyboxCam == (Object)null}'");
						if ((Object)(object)__instance.sceneCam != (Object)null)
						{
							__instance.sceneCam.targetDisplay = display;
						}
						if ((Object)(object)__instance.uiCam != (Object)null)
						{
							__instance.uiCam.targetDisplay = display;
						}
						if ((Object)(object)__instance.skyboxCam != (Object)null)
						{
							__instance.skyboxCam.targetDisplay = display;
						}
					}
				}
			});
		}

		private static void UpdateMPEventHooks(bool isSplitscreenEnabled)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if ((object)MPEventSystem_OnLastActiveControllerChanged_Orig == null)
			{
				MPEventSystem_OnLastActiveControllerChanged_Orig = typeof(MPEventSystem).GetMethod("OnLastActiveControllerChanged", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if ((object)MPEventSystem_OnLastActiveControllerChanged_Patch == null)
			{
				MPEventSystem_OnLastActiveControllerChanged_Patch = typeof(HookManager).GetMethod("MPEventSystem_OnLastActiveControllerChanged", BindingFlags.Static | BindingFlags.NonPublic);
			}
			if (isSplitscreenEnabled)
			{
				Plugin.Patcher.Patch((MethodBase)MPEventSystem_OnLastActiveControllerChanged_Orig, (HarmonyMethod)null, new HarmonyMethod(MPEventSystem_OnLastActiveControllerChanged_Patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				Plugin.Patcher.Unpatch((MethodBase)MPEventSystem_OnLastActiveControllerChanged_Orig, MPEventSystem_OnLastActiveControllerChanged_Patch);
			}
		}

		private static void MPEventSystem_OnLastActiveControllerChanged(MPEventSystem __instance, Player __0, Controller __1)
		{
			if (__1 == null)
			{
				__instance.currentInputSource = (InputSource)1;
			}
		}

		private static void UpdateSubscriptions(bool isSplitscreenEnabled)
		{
			if (isSplitscreenEnabled)
			{
				ReInput.ControllerConnectedEvent += OnControllerConnected;
			}
			else
			{
				ReInput.ControllerConnectedEvent -= OnControllerConnected;
			}
		}

		private static void OnControllerConnected(ControllerStatusChangedEventArgs args)
		{
			IReadOnlyList<LocalUser> localUsers = SplitscreenUserManager.LocalUsers;
			foreach (LocalUser item in localUsers)
			{
				if (item.InputPlayer.controllers.joystickCount == 0)
				{
					item.InputPlayer.controllers.AddController(args.controller, true);
				}
			}
		}

		private static void UpdateCameraRects(bool isSplitscreenEnabled)
		{
			//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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo field = typeof(RunCameraManager).GetField("ScreenLayouts", BindingFlags.Static | BindingFlags.Public);
			Rect[][] array = new Rect[5][]
			{
				(Rect[])(object)new Rect[0],
				(Rect[])(object)new Rect[1]
				{
					new Rect(0f, 0f, 1f, 1f)
				},
				(Rect[])(object)new Rect[2]
				{
					new Rect(0f, 0.5f, 1f, 0.5f),
					new Rect(0f, 0f, 1f, 0.5f)
				},
				(Rect[])(object)new Rect[3]
				{
					new Rect(0f, 0.5f, 1f, 0.5f),
					new Rect(0f, 0f, 0.5f, 0.5f),
					new Rect(0.5f, 0f, 0.5f, 0.5f)
				},
				(Rect[])(object)new Rect[4]
				{
					new Rect(0f, 0.5f, 0.5f, 0.5f),
					new Rect(0.5f, 0.5f, 0.5f, 0.5f),
					new Rect(0f, 0f, 0.5f, 0.5f),
					new Rect(0.5f, 0f, 0.5f, 0.5f)
				}
			};
			if (isSplitscreenEnabled)
			{
				IReadOnlyList<LocalUser> localUsers = SplitscreenUserManager.LocalUsers;
				array = new Rect[localUsers.Count + 1][];
				array[0] = (Rect[])(object)new Rect[0];
				array[1] = (Rect[])(object)new Rect[1]
				{
					new Rect(0f, 0f, 1f, 1f)
				};
				Rect[] array2 = (Rect[])(object)new Rect[localUsers.Count];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = localUsers[i].CameraRect;
					Log.Print($"Adding '{localUsers[i].UserIndex}' with rect '{localUsers[i].CameraRect}'");
				}
				array[localUsers.Count] = array2;
			}
			field.SetValue(null, array);
			for (int j = 0; j < array.Length; j++)
			{
				if (array[j] != null)
				{
					for (int k = 0; k < array[j].Length; k++)
					{
						Log.Print($"Rect[{j}][{k}] -> {array[j][k]}");
					}
				}
			}
		}

		private static void UpdatePauseScreenBehaviourHook(bool isSplitscreenEnabled)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			if ((object)PauseStopController_allowMultiplayerPause_Orig == null)
			{
				PauseStopController_allowMultiplayerPause_Orig = typeof(PauseStopController).GetProperty("allowMultiplayerPause", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetSetMethod(nonPublic: true);
			}
			if ((object)PauseStopController_allowMultiplayerPause_Patch == null)
			{
				PauseStopController_allowMultiplayerPause_Patch = typeof(HookManager).GetMethod("PauseStopController_allowMultiplayerPause", BindingFlags.Static | BindingFlags.NonPublic);
			}
			if (!(PauseStopController_allowMultiplayerPause_Orig == null))
			{
				if (isSplitscreenEnabled)
				{
					Plugin.Patcher.Patch((MethodBase)PauseStopController_allowMultiplayerPause_Orig, new HarmonyMethod(PauseStopController_allowMultiplayerPause_Patch), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Patcher.Unpatch((MethodBase)PauseStopController_allowMultiplayerPause_Orig, PauseStopController_allowMultiplayerPause_Patch);
				}
			}
		}

		private static bool PauseStopController_allowMultiplayerPause(PauseStopController __instance, bool __0)
		{
			__instance.Network_allowMultiplayerPause = !SplitscreenUserManager.OnlineMode || __0;
			return false;
		}
	}
	internal static class Log
	{
		[Flags]
		internal enum ELogChannel
		{
			None = 1,
			Message = 2,
			Info = 4,
			Warning = 8,
			Error = 0x10,
			Fatal = 0x20,
			Debug = 0x40,
			All = 0x80
		}

		private static ELogChannel ActiveChannels = ELogChannel.None;

		private static ManualLogSource Source;

		internal static void Init(ManualLogSource source, ELogChannel channels)
		{
			Source = source;
			SetActiveChannels(channels);
		}

		internal static void SetActiveChannels(ELogChannel channels)
		{
			ActiveChannels = channels;
			Source.LogMessage((object)$"Set log channels to '{channels}'");
		}

		internal static void Print(object data, ELogChannel channel = ELogChannel.Debug)
		{
			if (ActiveChannels.HasFlag(ELogChannel.All) || ActiveChannels.HasFlag(channel))
			{
				if (channel.HasFlag(ELogChannel.Message))
				{
					Source.LogMessage(data);
				}
				else if (channel.HasFlag(ELogChannel.Info))
				{
					Source.LogInfo(data);
				}
				else if (channel.HasFlag(ELogChannel.Warning))
				{
					Source.LogWarning(data);
				}
				else if (channel.HasFlag(ELogChannel.Error))
				{
					Source.LogError(data);
				}
				else if (channel.HasFlag(ELogChannel.Fatal))
				{
					Source.LogFatal(data);
				}
				else if (channel.HasFlag(ELogChannel.Debug))
				{
					Source.LogDebug(data);
				}
			}
		}
	}
	public enum TrailType
	{
		Ribbon,
		Particles,
		Flare,
		MeshFountain
	}
	public static class ParticleSystemFactory
	{
		private static Transform _systemContainer;

		private static readonly Dictionary<string, GameObject> _particleSystemCache = new Dictionary<string, GameObject>();

		public static ParticleSystem CreateParticleSystem(string key, TrailType trailType, Material material, Color color, bool useTextureColor = false, float lifetime = 1f, float length = 1f, float width = 0.1f, float rateOverDistance = 0f, float emissionRate = 10f, Mesh meshAsset = null, Material trailMaterial = null)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_008d: 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)
			if (_particleSystemCache.ContainsKey(key))
			{
				Debug.LogWarning((object)("ParticleSystem with key '" + key + "' already exists in cache. Use GetParticleSystem instead."));
				return ((Component)GetParticleSystem(key)).GetComponent<ParticleSystem>();
			}
			if ((Object)(object)_systemContainer == (Object)null)
			{
				_systemContainer = new GameObject("XSS Particle Systems").transform;
				Object.DontDestroyOnLoad((Object)(object)_systemContainer);
			}
			GameObject val = new GameObject("ParticleSystem_" + key);
			val.SetActive(false);
			ParticleSystem val2 = val.AddComponent<ParticleSystem>();
			ConfigureParticleSystem(val2, trailType, material, color, useTextureColor, lifetime, length, width, emissionRate, rateOverDistance, meshAsset, trailMaterial);
			val.transform.SetParent(_systemContainer);
			_particleSystemCache[key] = val;
			return val2;
		}

		public static string[] GetParticleSystemKeys()
		{
			return _particleSystemCache.Keys.ToArray();
		}

		public static Transform GetParticleSystem(string key)
		{
			if (!_particleSystemCache.TryGetValue(key, out var value))
			{
				Debug.LogError((object)("No particle system found with key '" + key + "'"));
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(value);
			((Object)val).name = "ParticleSystem_" + key + "_Clone";
			return val.transform;
		}

		private static void ConfigureParticleSystem(ParticleSystem particleSystem, TrailType trailType, Material material, Color color, bool useTextureColor, float lifetime, float length, float width, float emissionRate, float rateOverDistance, Mesh meshAsset, Material trailMaterial)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0077: 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)
			//IL_0065: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			MainModule main = particleSystem.main;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(lifetime);
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(width);
			((MainModule)(ref main)).maxParticles = Mathf.CeilToInt(emissionRate * lifetime * 1.5f);
			if (!useTextureColor)
			{
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(color);
			}
			else
			{
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.white);
			}
			EmissionModule emission = particleSystem.emission;
			((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(emissionRate);
			ParticleSystemRenderer component = ((Component)particleSystem).GetComponent<ParticleSystemRenderer>();
			((Renderer)component).material = material;
			component.sortingFudge = 0f;
			switch (trailType)
			{
			case TrailType.Ribbon:
				ConfigureRibbonTrail(particleSystem, component, length, width, trailMaterial);
				break;
			case TrailType.Particles:
				ConfigureParticleTrail(particleSystem, component, length, width, rateOverDistance);
				break;
			case TrailType.Flare:
				ConfigureFlare(particleSystem, component, width);
				break;
			case TrailType.MeshFountain:
				ConfigureMeshFountain(particleSystem, component, meshAsset, length);
				break;
			}
			OptimizeParticleSystem(particleSystem);
		}

		private static void ConfigureRibbonTrail(ParticleSystem particleSystem, ParticleSystemRenderer renderer, float length, float width, Material trailMaterial)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			TrailModule trails = particleSystem.trails;
			((TrailModule)(ref trails)).enabled = true;
			((TrailModule)(ref trails)).mode = (ParticleSystemTrailMode)1;
			((TrailModule)(ref trails)).ratio = 1f;
			((TrailModule)(ref trails)).lifetime = MinMaxCurve.op_Implicit(length);
			((TrailModule)(ref trails)).widthOverTrail = MinMaxCurve.op_Implicit(width);
			((TrailModule)(ref trails)).dieWithParticles = true;
			((TrailModule)(ref trails)).sizeAffectsWidth = false;
			MainModule main = particleSystem.main;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(length + 0.1f);
			renderer.alignment = (ParticleSystemRenderSpace)0;
			renderer.renderMode = (ParticleSystemRenderMode)1;
			renderer.trailMaterial = trailMaterial;
		}

		private static void ConfigureParticleTrail(ParticleSystem particleSystem, ParticleSystemRenderer renderer, float length, float width, float rateOverDistance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			renderer.renderMode = (ParticleSystemRenderMode)0;
			EmissionModule emission = particleSystem.emission;
			((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(rateOverDistance);
			VelocityOverLifetimeModule velocityOverLifetime = particleSystem.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)1;
		}

		private static void ConfigureFlare(ParticleSystem particleSystem, ParticleSystemRenderer renderer, float width)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_002f: 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_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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00cd: Expected O, but got Unknown
			//IL_00d6: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0103: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			MainModule main = particleSystem.main;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.5f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(width * 1.5f);
			VelocityOverLifetimeModule velocityOverLifetime = particleSystem.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false;
			RotationOverLifetimeModule rotationOverLifetime = particleSystem.rotationOverLifetime;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).separateAxes = false;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(0f, 360f);
			SizeOverLifetimeModule sizeOverLifetime = particleSystem.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
			AnimationCurve val = new AnimationCurve((Keyframe[])(object)new Keyframe[3]
			{
				new Keyframe(0f, 0.8f),
				new Keyframe(0.5f, 1.2f),
				new Keyframe(1f, 0.8f)
			});
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val);
			ColorOverLifetimeModule colorOverLifetime = particleSystem.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			Gradient val2 = new Gradient();
			val2.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
			{
				new GradientColorKey(Color.white, 0f),
				new GradientColorKey(Color.white, 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[4]
			{
				new GradientAlphaKey(0f, 0f),
				new GradientAlphaKey(1f, 0.1f),
				new GradientAlphaKey(1f, 0.9f),
				new GradientAlphaKey(0f, 1f)
			});
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val2);
			renderer.renderMode = (ParticleSystemRenderMode)0;
		}

		private static void ConfigureMeshFountain(ParticleSystem particleSystem, ParticleSystemRenderer renderer, Mesh meshAsset, float length)
		{
			//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)
			//IL_003f: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00e4: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)meshAsset == (Object)null)
			{
				Debug.LogError((object)"Mesh asset is required for MeshFountain trail type");
				return;
			}
			renderer.renderMode = (ParticleSystemRenderMode)4;
			renderer.mesh = meshAsset;
			MainModule main = particleSystem.main;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(length * 0.5f);
			MinMaxCurve startSpeed = ((MainModule)(ref main)).startSpeed;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(length / ((MinMaxCurve)(ref startSpeed)).constant * 2f);
			((MainModule)(ref main)).startRotation3D = true;
			((MainModule)(ref main)).startRotationX = new MinMaxCurve(0f, 360f);
			((MainModule)(ref main)).startRotationY = new MinMaxCurve(0f, 360f);
			((MainModule)(ref main)).startRotationZ = new MinMaxCurve(0f, 360f);
			ShapeModule shape = particleSystem.shape;
			((ShapeModule)(ref shape)).enabled = true;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
			((ShapeModule)(ref shape)).angle = 15f;
			LimitVelocityOverLifetimeModule limitVelocityOverLifetime = particleSystem.limitVelocityOverLifetime;
			((LimitVelocityOverLifetimeModule)(ref limitVelocityOverLifetime)).enabled = true;
			((LimitVelocityOverLifetimeModule)(ref limitVelocityOverLifetime)).dampen = 0.1f;
			RotationOverLifetimeModule rotationOverLifetime = particleSystem.rotationOverLifetime;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).separateAxes = true;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).x = new MinMaxCurve(0f, 90f);
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).y = new MinMaxCurve(0f, 90f);
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(0f, 90f);
		}

		private static void OptimizeParticleSystem(ParticleSystem particleSystem)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			NoiseModule noise = particleSystem.noise;
			((NoiseModule)(ref noise)).enabled = false;
			LightsModule lights = particleSystem.lights;
			((LightsModule)(ref lights)).enabled = false;
			CollisionModule collision = particleSystem.collision;
			((CollisionModule)(ref collision)).enabled = false;
			TextureSheetAnimationModule textureSheetAnimation = particleSystem.textureSheetAnimation;
			((TextureSheetAnimationModule)(ref textureSheetAnimation)).enabled = false;
			MainModule main = particleSystem.main;
			((MainModule)(ref main)).useUnscaledTime = false;
			((MainModule)(ref main)).simulationSpeed = 1f;
			((MainModule)(ref main)).cullingMode = (ParticleSystemCullingMode)0;
			((MainModule)(ref main)).prewarm = false;
			ParticleSystemRenderer component = ((Component)particleSystem).GetComponent<ParticleSystemRenderer>();
			component.enableGPUInstancing = true;
			component.minParticleSize = 0.01f;
			component.maxParticleSize = 0.5f;
			component.allowRoll = false;
		}

		public static void CreateAllParticleSystems()
		{
			CreateLemonDot();
			CreateSparkleDust();
			CreateDarkVoid();
			CreateHearts();
			CreateSkulls();
			CreateBluePulse();
		}

		private static void CreateLemonDot()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0010: 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_001f: 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_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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			Gradient val = new Gradient();
			val.SetKeys((GradientColorKey[])(object)new GradientColorKey[2]
			{
				new GradientColorKey(Color.yellow, 0f),
				new GradientColorKey(new Color(1f, 0.95f, 0.8f), 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[3]
			{
				new GradientAlphaKey(1f, 0f),
				new GradientAlphaKey(1f, 0.75f),
				new GradientAlphaKey(0f, 1f)
			});
			int num = 16;
			float num2 = 35f;
			float num3 = MathF.PI / 180f;
			AnimationCurve val2 = new AnimationCurve();
			for (int i = 0; i <= num * 2; i++)
			{
				float num4 = (float)i / (float)(num * 2);
				float num5 = Mathf.Sin(num4 * MathF.PI * (float)num) * num2 * num3;
				val2.AddKey(num4, num5);
			}
			Material val3 = new Material(Plugin.Resources.LoadAsset<Material>("ParticleMat_A.mat"));
			Texture2D val4 = Plugin.Resources.LoadAsset<Texture2D>("lemon.png");
			Material val5 = new Material(val3);
			val5.SetTexture("_MainTex", (Texture)(object)val4);
			ParticleSystem val6 = CreateParticleSystem("LemonDot", TrailType.Particles, val5, new Color(1f, 1f, 0.8f), useTextureColor: true, 8f, 1f, 0.4f, 1f, 1f);
			ShapeModule shape = val6.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 2.53f;
			((ShapeModule)(ref shape)).radiusThickness = 0.18f;
			ColorOverLifetimeModule colorOverLifetime = val6.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val);
			RotationOverLifetimeModule rotationOverLifetime = val6.rotationOverLifetime;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).enabled = true;
			((RotationOverLifetimeModule)(ref rotationOverLifetime)).z = new MinMaxCurve(1.5f, val2);
			SizeOverLifetimeModule sizeOverLifetime = val6.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
			AnimationCurve val7 = new AnimationCurve((Keyframe[])(object)new Keyframe[5]
			{
				new Keyframe(0f, 1.2f),
				new Keyframe(0.2f, 1f),
				new Keyframe(0.5f, 1.3f),
				new Keyframe(0.8f, 1f),
				new Keyframe(1f, 1.2f)
			});
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val7);
		}

		private static void CreateSparkleDust()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0113: Expected O, but got Unknown
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			Gradient val = new Gradient();
			val.SetKeys((GradientColorKey[])(object)new GradientColorKey[3]
			{
				new GradientColorKey(new Color(1f, 0.95f, 0.8f), 0f),
				new GradientColorKey(new Color(0.8f, 0.95f, 1f), 0.5f),
				new GradientColorKey(new Color(1f, 1f, 0.9f), 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[6]
			{
				new GradientAlphaKey(0f, 0f),
				new GradientAlphaKey(0.8f, 0.18f),
				new GradientAlphaKey(1f, 0.3f),
				new GradientAlphaKey(1f, 0.7f),
				new GradientAlphaKey(0.3f, 0.85f),
				new GradientAlphaKey(0f, 1f)
			});
			AnimationCurve val2 = new AnimationCurve();
			val2.AddKey(0f, 0f);
			val2.AddKey(0.062f, 0.8f);
			val2.AddKey(0.125f, 1.2f);
			val2.AddKey(0.188f, 0.6f);
			val2.AddKey(0.25f, 1f);
			val2.AddKey(0.312f, 0.7f);
			val2.AddKey(0.375f, 0.8f);
			val2.AddKey(0.438f, 1.2f);
			val2.AddKey(0.5f, 0.6f);
			val2.AddKey(0.562f, 1f);
			val2.AddKey(0.625f, 0.7f);
			val2.AddKey(0.688f, 0.8f);
			val2.AddKey(0.75f, 1.2f);
			val2.AddKey(0.812f, 0.6f);
			val2.AddKey(0.875f, 1f);
			val2.AddKey(0.938f, 0.7f);
			val2.AddKey(1f, 0f);
			Material val3 = new Material(Plugin.Resources.LoadAsset<Material>("ParticleMat_A.mat"));
			val3.SetTexture("_MainTex", (Texture)(object)Plugin.Resources.LoadAsset<Texture2D>("flare_02.png"));
			ParticleSystem val4 = CreateParticleSystem("SparkleDust", TrailType.Particles, val3, Color.white, useTextureColor: true, 2.1f, 1f, 0.15f, 1f);
			MainModule main = val4.main;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.08f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.07f, 0.15f);
			VelocityOverLifetimeModule velocityOverLifetime = val4.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(-0.15f, 0.15f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(0.09f, 0.18f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(-0.13f, 0.13f);
			SizeOverLifetimeModule sizeOverLifetime = val4.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val2);
			ColorOverLifetimeModule colorOverLifetime = val4.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val);
			ShapeModule shape = val4.shape;
			((ShapeModule)(ref shape)).enabled = true;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 0.7f;
			((ShapeModule)(ref shape)).radiusThickness = 0.18f;
		}

		private static void CreateHearts()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0113: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			Gradient val = new Gradient();
			val.SetKeys((GradientColorKey[])(object)new GradientColorKey[3]
			{
				new GradientColorKey(new Color(1f, 0.95f, 0.8f), 0f),
				new GradientColorKey(new Color(0.8f, 0.95f, 1f), 0.5f),
				new GradientColorKey(new Color(1f, 1f, 0.9f), 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[6]
			{
				new GradientAlphaKey(0f, 0f),
				new GradientAlphaKey(0.8f, 0.18f),
				new GradientAlphaKey(1f, 0.3f),
				new GradientAlphaKey(1f, 0.7f),
				new GradientAlphaKey(0.3f, 0.85f),
				new GradientAlphaKey(0f, 1f)
			});
			AnimationCurve val2 = new AnimationCurve();
			val2.AddKey(0.1f, 0.8f);
			val2.AddKey(0.3f, 1.2f);
			val2.AddKey(0.5f, 0.6f);
			val2.AddKey(0.7f, 1f);
			val2.AddKey(0.9f, 0.7f);
			Material val3 = new Material(Plugin.Resources.LoadAsset<Material>("ParticleMat_A.mat"));
			val3.SetTexture("_MainTex", (Texture)(object)Plugin.Resources.LoadAsset<Texture2D>("heart_02.png"));
			ParticleSystem val4 = CreateParticleSystem("Hearts", TrailType.Particles, val3, Color.white, useTextureColor: true, 1.1f, 1f, 0.25f, 1f, 4f);
			MainModule main = val4.main;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.08f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.17f, 0.25f);
			VelocityOverLifetimeModule velocityOverLifetime = val4.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(-0.15f, 0.15f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(0.09f, 0.18f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(-0.13f, 0.13f);
			SizeOverLifetimeModule sizeOverLifetime = val4.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val2);
			ColorOverLifetimeModule colorOverLifetime = val4.colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val);
			ShapeModule shape = val4.shape;
			((ShapeModule)(ref shape)).enabled = true;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0;
			((ShapeModule)(ref shape)).radius = 2.7f;
			((ShapeModule)(ref shape)).radiusThickness = 0.18f;
		}

		private static void CreateSkulls()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0113: Expected O, but got Unknown
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Expected O, but got Unknown
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			Gradient val = new Gradient();
			val.SetKeys((GradientColorKey[])(object)new GradientColorKey[3]
			{
				new GradientColorKey(new Color(1f, 0.95f, 0.8f), 0f),
				new GradientColorKey(new Color(0.8f, 0.95f, 1f), 0.5f),
				new GradientColorKey(new Color(1f, 1f, 0.9f), 1f)
			}, (GradientAlphaKey[])(object)new GradientAlphaKey[6]
			{
				new GradientAlphaKey(0f, 0f),
				new GradientAlphaKey(0.8f, 0.18f),
				new GradientAlphaKey(1f, 0.3f),
				new GradientAlphaKey(1f, 0.7f),
				new GradientAlphaKey(0.3f, 0.85f),
				new GradientAlphaKey(0f, 1f)
			});
			AnimationCurve val2 = new AnimationCurve();
			val2.AddKey(0f, 0f);
			val2.AddKey(0.062f, 0.9f);
			val2.AddKey(0.125f, 1.1f);
			val2.AddKey(0.188f, 0.9f);
			val2.AddKey(0.25f, 1.1f);
			val2.AddKey(0.312f, 0.9f);
			val2.AddKey(0.375f, 1f);
			val2.AddKey(0.438f, 0.9f);
			val2.AddKey(0.5f, 1.1f);
			val2.AddKey(0.562f, 0.9f);
			val2.AddKey(0.625f, 1.1f);
			val2.AddKey(0.688f, 0.9f);
			val2.AddKey(0.75f, 1.1f);
			val2.AddKey(0.812f, 0.9f);
			val2.AddKey(0.875f, 1.1f);
			val2.AddKey(0.938f, 0.9f);
			val2.AddKey(1f, 0f);
			Material val3 = new Material(Plugin.Resources.LoadAsset<Material>("ParticleMat_A.mat"));
			val3.SetTexture("_MainTex", (Texture)(object)Plugin.Resources.LoadAsset<Texture2D>("skull_01.png"));
			ParticleSystem val4 = CreateParticleSystem("Skulls", TrailType.Particles, val3, Color.white, useTextureColor: true, 1.4f, 1f, 0.5f, 1f, 4f);
			MainModule main = val4.main;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.04f);
			((MainModule)(ref main)).startSize = new MinMaxCurve(0.17f, 0.25f);
			VelocityOverLifetimeModule velocityOverLifetime = val4.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = true;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = new MinMaxCurve(0f);
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = new MinMaxCurve(0f);
			AnimationCurve val5 = new AnimationCurve((Keyframe[])(object)new Keyframe[5]
			{
				new Keyframe(0f, 0.1f),
				new Keyframe(0.25f, -0.1f),
				new Keyframe(0.5f, 0.1f),
				new Keyframe(0.75f, -0.1f),
				new Keyframe(1f, 0.1f)
			});
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = new MinMaxCurve(1f, val5);
			SizeOverLifetimeModule sizeOverLifetime = val4.sizeOverLifetime;
			(