Decompiled source of Soulmates v0.2.7

plugins/com.github.Wesmania.Soulmates.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;
using pworld.Scripts.Extensions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.github.Wesmania.Soulmates")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.7.0")]
[assembly: AssemblyInformationalVersion("0.2.7+ba64a1572ea41b22017ff12e823911772ce46a02")]
[assembly: AssemblyProduct("com.github.Wesmania.Soulmates")]
[assembly: AssemblyTitle("Soulmates")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.7.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace Soulmates
{
	internal static class AfflictionUtil
	{
		public static bool sharedLolli()
		{
			if (Plugin.previousSoulmates.HasValue)
			{
				return Plugin.previousSoulmates.Value.config.sharedLolli;
			}
			return false;
		}

		public static bool sharedEnergol()
		{
			if (Plugin.previousSoulmates.HasValue)
			{
				return Plugin.previousSoulmates.Value.config.sharedEnergol;
			}
			return false;
		}

		public static void onSharedAfflictionEvent(EventData photonEvent)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			object[] array = (object[])photonEvent.CustomData;
			SharedAffliction sharedAffliction = SharedAffliction.Deserialize((string)array[1]);
			int sender = photonEvent.Sender;
			if (Plugin.localCharIsReady())
			{
				Character localCharacter = Character.localCharacter;
				if (Soulmates.ActorIsSoulmate(sender))
				{
					Affliction val = Affliction.CreateBlankAffliction(sharedAffliction.type);
					val.totalTime = sharedAffliction.totalTime;
					AfflictionPatch.skipMessage = true;
					localCharacter.refs.afflictions.AddAffliction(val, false);
					AfflictionPatch.skipMessage = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions))]
	public static class AfflictionPatch
	{
		public static bool skipMessage;

		[HarmonyPostfix]
		[HarmonyPatch("AddAffliction", new Type[]
		{
			typeof(Affliction),
			typeof(bool)
		})]
		public static void AddAfflictionPostfix(CharacterAfflictions __instance, Affliction affliction, bool fromRPC)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_0037: 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)
			if (__instance.character.IsLocal && __instance.character.isLiv() && !skipMessage)
			{
				SharedAffliction e = default(SharedAffliction);
				if ((int)affliction.GetAfflictionType() == 1 && AfflictionUtil.sharedLolli())
				{
					e.type = (AfflictionType)1;
					e.totalTime = affliction.totalTime;
					Events.SendSharedAfflictionEvent(e);
				}
				if ((int)affliction.GetAfflictionType() == 2 && AfflictionUtil.sharedEnergol())
				{
					e.type = (AfflictionType)2;
					e.totalTime = affliction.totalTime;
					Events.SendSharedAfflictionEvent(e);
				}
			}
		}
	}
	public static class Bonk
	{
		public static void OnSharedBonkEvent(EventData photonEvent)
		{
			//IL_0056: 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)
			object[] array = (object[])photonEvent.CustomData;
			SharedBonk sharedBonk = SharedBonk.Deserialize((string)array[1]);
			int sender = photonEvent.Sender;
			if (Plugin.localCharIsReady())
			{
				Character localCharacter = Character.localCharacter;
				if (Soulmates.ActorIsSoulmate(sharedBonk.victim))
				{
					localCharacter.Fall(sharedBonk.ragdollTime, 0f);
					localCharacter.AddForceAtPosition(sharedBonk.force.toVector3(), sharedBonk.contactPoint.toVector3(), sharedBonk.range);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Bonkable))]
	public static class BonkPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch("Bonk", new Type[] { typeof(Collision) })]
		public static void BonkPrefix(Bonkable __instance, Collision coll)
		{
			//IL_0061: 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_0069: 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_0079: 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)
			Character componentInParent = coll.gameObject.GetComponentInParent<Character>();
			if (Object.op_Implicit((Object)(object)componentInParent) && Time.time > __instance.lastBonkedTime + __instance.bonkCooldown && Plugin.previousSoulmates.HasValue && Plugin.previousSoulmates.Value.config.sharedBonk)
			{
				SharedBonk e = default(SharedBonk);
				e.ragdollTime = __instance.ragdollTime;
				Vector3 relativeVelocity = coll.relativeVelocity;
				e.force = new V3(-((Vector3)(ref relativeVelocity)).normalized * __instance.bonkForce);
				e.contactPoint = new V3(((ContactPoint)(ref coll.contacts[0])).point);
				e.range = __instance.bonkRange;
				e.victim = ((MonoBehaviourPun)componentInParent).photonView.Owner.ActorNumber;
				Events.SendSharedBonkEvent(e);
			}
		}
	}
	public static class Colors
	{
		public static Color soulmateColor = new Color(3f / 32f, 0.86328125f, 0.15234375f);

		public static Color[] c = (Color[])(object)new Color[10]
		{
			new Color(0.83984375f, 0.12890625f, 0.12890625f),
			new Color(51f / 128f, 31f / 64f, 0.99609375f),
			new Color(0.91015625f, 0.8125f, 0.3125f),
			new Color(0.63671875f, 11f / 32f, 57f / 64f),
			new Color(19f / 64f, 0.90234375f, 57f / 64f),
			new Color(0.80859375f, 0.40234375f, 3f / 32f),
			new Color(127f / 128f, 0.23828125f, 109f / 128f),
			new Color(0.59765625f, 0.59765625f, 0.59765625f),
			new Color(69f / 128f, 11f / 32f, 0f),
			new Color(7f / 64f, 0.09765625f, 0.52734375f)
		};

		public static Color getColor(int idx)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (idx < c.Length)
			{
				return c[idx];
			}
			return Color.white;
		}
	}
	public static class ConnectSoulmate
	{
		private static int globalConnectedSoulmateCount;

		public static int ConnectedToSoulmateCount()
		{
			if (!Plugin.localCharIsReady())
			{
				return 0;
			}
			if (!Character.localCharacter.isLiv())
			{
				return 0;
			}
			return Soulmates.LiveSoulmateCount();
		}

		public static void UpdateSoulmateStatus()
		{
			if (!((Object)(object)Character.localCharacter == (Object)null))
			{
				int num = ConnectedToSoulmateCount();
				if (num != globalConnectedSoulmateCount)
				{
					UpdateConnectedSoulmates();
				}
			}
		}

		private static void UpdateConnectedSoulmates()
		{
			if (Plugin.localCharIsReady())
			{
				Character localCharacter = Character.localCharacter;
				localCharacter.refs.afflictions.UpdateWeight();
			}
		}
	}
	public class EventCache
	{
		public static EventCache instance = new EventCache();

		private Dictionary<(STATUSTYPE, SharedDamageKind), float> cache = new Dictionary<(STATUSTYPE, SharedDamageKind), float>
		{
			{
				((STATUSTYPE)1, SharedDamageKind.ADD),
				0f
			},
			{
				((STATUSTYPE)1, SharedDamageKind.SUBTRACT),
				0f
			},
			{
				((STATUSTYPE)2, SharedDamageKind.ADD),
				0f
			},
			{
				((STATUSTYPE)2, SharedDamageKind.SUBTRACT),
				0f
			},
			{
				((STATUSTYPE)8, SharedDamageKind.ADD),
				0f
			},
			{
				((STATUSTYPE)8, SharedDamageKind.SUBTRACT),
				0f
			}
		};

		private float staminaCache;

		public SharedDamage? cacheEvent(SharedDamage e)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			(STATUSTYPE, SharedDamageKind) key = (e.type, e.kind);
			if (!cache.ContainsKey(key))
			{
				return e;
			}
			cache[key] += e.value;
			if (cache[key] < 0.01f)
			{
				return null;
			}
			e.value = cache[key];
			cache[key] = 0f;
			return e;
		}

		public SharedExtraStamina? cacheStamina(SharedExtraStamina e)
		{
			if (e.diff > 0f)
			{
				return e;
			}
			staminaCache += e.diff;
			if (staminaCache > -0.01f)
			{
				return null;
			}
			e.diff = staminaCache;
			staminaCache = 0f;
			return e;
		}
	}
	public static class Events
	{
		private static void SendEvent(SoulmateEventType eventType, string e, ReceiverGroup who, bool reliable = true)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			object[] array = new object[2]
			{
				(int)eventType,
				e
			};
			RaiseEventOptions val = new RaiseEventOptions
			{
				Receivers = who
			};
			SendOptions val2 = (reliable ? SendOptions.SendReliable : SendOptions.SendUnreliable);
			PhotonNetwork.RaiseEvent((byte)198, (object)array, val, val2);
		}

		private static void SendEventTo(SoulmateEventType eventType, string e, int[] targets, bool reliable = true)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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)
			object[] array = new object[2]
			{
				(int)eventType,
				e
			};
			RaiseEventOptions val = new RaiseEventOptions
			{
				TargetActors = targets
			};
			SendOptions val2 = (reliable ? SendOptions.SendReliable : SendOptions.SendUnreliable);
			PhotonNetwork.RaiseEvent((byte)198, (object)array, val, val2);
		}

		private static void SendToSoulmates(SoulmateEventType eventType, string e, bool reliable = true)
		{
			if (!Soulmates.NoSoulmates())
			{
				SendEventTo(eventType, e, Soulmates.SoulmateNumbers().ToArray(), reliable);
			}
		}

		public static void SendRecalculateSoulmateEvent(RecalculateSoulmatesEvent e)
		{
			Plugin.Log.LogInfo((object)"Sending recalculate soulmate event...");
			SendEvent(SoulmateEventType.RECALCULATE, e.Serialize(), (ReceiverGroup)1);
		}

		public static void SendSharedDamageEvent(SharedDamage e)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!e.type.isShared() || e.type.isAbsolute())
			{
				Plugin.Log.LogInfo((object)"$Tried to send a non-shared or absolute status type {statusType}");
				return;
			}
			SharedDamage? sharedDamage = EventCache.instance.cacheEvent(e);
			if (sharedDamage.HasValue)
			{
				e = sharedDamage.Value;
				bool reliable = true;
				if (e.kind != SharedDamageKind.SET && (double)math.abs(e.value) < 0.01)
				{
					reliable = false;
				}
				SendToSoulmates(SoulmateEventType.DAMAGE, e.Serialize(), reliable);
			}
		}

		public static void SendUpdateWeightEvent(UpdateWeight e)
		{
			SendEvent(SoulmateEventType.UPDATE_WEIGHT, e.Serialize(), (ReceiverGroup)0);
		}

		public static void SendSharedBonkEvent(SharedBonk e)
		{
			Plugin.Log.LogInfo((object)$"Sending bonk {e.victim} {e.ragdollTime} {e.force} {e.contactPoint} {e.range}");
			SendEvent(SoulmateEventType.SHARED_BONK, e.Serialize(), (ReceiverGroup)1);
		}

		public static void SendSharedExtraStaminaEvent(SharedExtraStamina e)
		{
			SharedExtraStamina? sharedExtraStamina = EventCache.instance.cacheStamina(e);
			if (sharedExtraStamina.HasValue)
			{
				e = sharedExtraStamina.Value;
				SendToSoulmates(SoulmateEventType.SHARED_EXTRA_STAMINA, e.Serialize());
			}
		}

		public static void SendSharedAfflictionEvent(SharedAffliction e)
		{
			SendToSoulmates(SoulmateEventType.SHARED_AFFLICTION, e.Serialize());
		}

		public static void SendWhoIsMySoulmatesEvent()
		{
			WhoIsMySoulmate whoIsMySoulmate = default(WhoIsMySoulmate);
			SendEvent(SoulmateEventType.WHO_IS_MY_SOULMATES, whoIsMySoulmate.Serialize(), (ReceiverGroup)0);
		}

		public static void SendThisIsYourSoulmatesEvent(RecalculateSoulmatesEvent e, int target)
		{
			SendEventTo(SoulmateEventType.RECALCULATE, e.Serialize(), new int[1] { target });
		}
	}
	internal static class StamUtil
	{
		public static float SingleStaminaMult()
		{
			return Plugin.GetSoulmateStrength();
		}

		public static bool sharedExtraStaminaUse()
		{
			if (Plugin.previousSoulmates.HasValue)
			{
				return Plugin.previousSoulmates.Value.config.sharedExtraStaminaUse;
			}
			return false;
		}

		public static bool sharedExtraStaminaGain()
		{
			if (Plugin.previousSoulmates.HasValue)
			{
				return Plugin.previousSoulmates.Value.config.sharedExtraStaminaGain;
			}
			return false;
		}

		public static bool onlySharesGain()
		{
			if (sharedExtraStaminaGain())
			{
				return !sharedExtraStaminaUse();
			}
			return false;
		}

		public static void OnSharedExtraStaminaEvent(EventData photonEvent)
		{
			object[] array = (object[])photonEvent.CustomData;
			SharedExtraStamina sharedExtraStamina = SharedExtraStamina.Deserialize((string)array[1]);
			int sender = photonEvent.Sender;
			if (Plugin.localCharIsReady())
			{
				Character localCharacter = Character.localCharacter;
				if (Soulmates.ActorIsSoulmate(sender))
				{
					StaminaPatch.skipMessage++;
					localCharacter.AddExtraStamina(sharedExtraStamina.diff * SingleStaminaMult());
					StaminaPatch.skipMessage--;
				}
			}
		}

		public static float MyStaminaGain()
		{
			float soulmateStrength = Plugin.GetSoulmateStrength();
			int soulmateGroupSize = Plugin.GetSoulmateGroupSize();
			float num = 1f + soulmateStrength * (float)(soulmateGroupSize - 1);
			return 1f / num;
		}

		public static float TheirStaminaGain()
		{
			float soulmateStrength = Plugin.GetSoulmateStrength();
			int soulmateGroupSize = Plugin.GetSoulmateGroupSize();
			float num = 1f + soulmateStrength * (float)(soulmateGroupSize - 1);
			return soulmateStrength / num;
		}
	}
	[HarmonyPatch(typeof(Character))]
	public static class StaminaPatch
	{
		public static int skipMessage;

		public static void SendStaminaDiff(Character __instance, float _diff)
		{
			if (!__instance.IsLocal || skipMessage > 0)
			{
				return;
			}
			float num = _diff;
			if (num != 0f && (!(num < 0f) || StamUtil.sharedExtraStaminaUse()) && (!(num > 0f) || StamUtil.sharedExtraStaminaGain()))
			{
				if (num > 0f)
				{
					num = ((!StamUtil.onlySharesGain()) ? (num * Plugin.GetSoulmateStrength()) : (num * StamUtil.TheirStaminaGain()));
				}
				if (num < 0f)
				{
					num *= Plugin.GetSoulmateStrength();
				}
				SharedExtraStamina e = default(SharedExtraStamina);
				e.diff = num;
				Events.SendSharedExtraStaminaEvent(e);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("UseStamina", new Type[]
		{
			typeof(float),
			typeof(bool)
		})]
		public static void UseStaminaPrefix(Character __instance, float usage, bool useBonusStamina, out float __state)
		{
			__state = __instance.data.extraStamina;
		}

		[HarmonyPostfix]
		[HarmonyPatch("UseStamina", new Type[]
		{
			typeof(float),
			typeof(bool)
		})]
		public static void UseStaminaSuffix(Character __instance, float usage, bool useBonusStamina, float __state)
		{
			if (__instance.IsLocal)
			{
				SendStaminaDiff(__instance, __instance.data.extraStamina - __state);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetExtraStamina", new Type[] { typeof(float) })]
		public static void SetExtraStaminaPrefix(Character __instance, float amt, out float __state)
		{
			__state = __instance.data.extraStamina;
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetExtraStamina", new Type[] { typeof(float) })]
		public static void SetExtraStaminaSuffix(Character __instance, float amt, float __state)
		{
			if (__instance.IsLocal)
			{
				float num = __instance.data.extraStamina - __state;
				if (num > 0f && StamUtil.onlySharesGain())
				{
					skipMessage++;
					float num2 = num * StamUtil.MyStaminaGain();
					__instance.AddExtraStamina(num2 - num);
					skipMessage--;
				}
				SendStaminaDiff(__instance, num);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("AddExtraStamina", new Type[] { typeof(float) })]
		public static void AddExtraStaminaPrefix(Character __instance, ref float add, out float __state)
		{
			__state = add;
			if (__instance.IsLocal && add > 0f && StamUtil.onlySharesGain())
			{
				add *= StamUtil.MyStaminaGain();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("AddExtraStamina", new Type[] { typeof(float) })]
		public static void AddExtraStaminaSuffix(Character __instance, float add, float __state)
		{
			if (__instance.IsLocal)
			{
				SendStaminaDiff(__instance, __state);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterAfflictions))]
	public class SharedDamagePatch
	{
		internal static readonly HashSet<int> isReceivingSharedDamage = new HashSet<int>();

		internal static readonly Dictionary<int, int> isRecursiveStatusCall = new Dictionary<int, int>();

		private static HashSet<float> SoulmateValues = new HashSet<float>();

		public static void StatusPostfix(CharacterAfflictions __instance, SharedDamage _e)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (__instance.character.IsLocal && !__instance.character.data.dead && !__instance.character.warping && !isReceivingSharedDamage.Contains(((MonoBehaviourPun)__instance.character).photonView.ViewID))
				{
					SharedDamage e = _e;
					if (!e.type.isAbsolute() && e.type.isShared())
					{
						Events.SendSharedDamageEvent(e);
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Error in SetStatusPostfix: {arg}");
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetStatus", new Type[]
		{
			typeof(STATUSTYPE),
			typeof(float),
			typeof(bool)
		})]
		public static void SetStatusPrefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount, bool pushStatus, out float __state)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			__state = __instance.GetCurrentStatus(statusType);
			if (statusType.isAbsolute())
			{
				amount = Weight.PreSetWeight(__instance, statusType, amount);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("SetStatus", new Type[]
		{
			typeof(STATUSTYPE),
			typeof(float),
			typeof(bool)
		})]
		public static void SetStatusPostfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool pushStatus, float __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			float currentStatus = __instance.GetCurrentStatus(statusType);
			float num = currentStatus - __state;
			if (num != 0f)
			{
				if (!statusType.isAbsolute())
				{
					SharedDamage e = default(SharedDamage);
					e.type = statusType;
					e.value = num;
					e.kind = SharedDamageKind.SET;
					StatusPostfix(__instance, e);
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("AddStatus", new Type[]
		{
			typeof(STATUSTYPE),
			typeof(float),
			typeof(bool),
			typeof(bool)
		})]
		public static void AddStatusPrefix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC, bool playEffects, out SharedDamage __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			__state.type = statusType;
			__state.value = amount;
			__state.kind = SharedDamageKind.ADD;
			if (!isRecursiveStatusCall.ContainsKey(((MonoBehaviourPun)__instance.character).photonView.ViewID))
			{
				isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID] = 0;
			}
			isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID]++;
		}

		[HarmonyPostfix]
		[HarmonyPatch("AddStatus", new Type[]
		{
			typeof(STATUSTYPE),
			typeof(float),
			typeof(bool),
			typeof(bool)
		})]
		public static void AddStatusPostfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC, bool playEffects, SharedDamage __state)
		{
			isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID]--;
			if (isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID] == 0)
			{
				StatusPostfix(__instance, __state);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("SubtractStatus", new Type[]
		{
			typeof(STATUSTYPE),
			typeof(float),
			typeof(bool),
			typeof(bool)
		})]
		public static void SubtractStatusPrefix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC, bool decreasedNaturally, out SharedDamage __state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			__state.type = statusType;
			__state.value = amount;
			__state.kind = SharedDamageKind.SUBTRACT;
			if (!isRecursiveStatusCall.ContainsKey(((MonoBehaviourPun)__instance.character).photonView.ViewID))
			{
				isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID] = 0;
			}
			isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID]++;
		}

		[HarmonyPostfix]
		[HarmonyPatch("SubtractStatus", new Type[]
		{
			typeof(STATUSTYPE),
			typeof(float),
			typeof(bool),
			typeof(bool)
		})]
		public static void SubtractStatusPostfix(CharacterAfflictions __instance, STATUSTYPE statusType, float amount, bool fromRPC, bool decreasedNaturally, SharedDamage __state)
		{
			isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID]--;
			if (isRecursiveStatusCall[((MonoBehaviourPun)__instance.character).photonView.ViewID] == 0)
			{
				StatusPostfix(__instance, __state);
			}
		}
	}
	[HarmonyPatch(typeof(Character))]
	public static class RecalculateSoulmatesPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("StartPassedOutOnTheBeach")]
		public static void StartPassedOutOnTheBeachPostfix(Character __instance)
		{
			Plugin.Log.LogInfo((object)"Passed out on the beach function");
			if (__instance.IsLocal)
			{
				RecalculateSoulmatesEvent? recalculateSoulmatesEvent = Plugin.RecalculateSoulmate(firstTime: true);
				if (recalculateSoulmatesEvent.HasValue)
				{
					Events.SendRecalculateSoulmateEvent(recalculateSoulmatesEvent.Value);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		public static void UpdatePostfix(Character __instance)
		{
			if (__instance.IsLocal)
			{
				ConnectSoulmate.UpdateSoulmateStatus();
				Weight.MaybeSendWeight();
			}
		}
	}
	[HarmonyPatch(typeof(Campfire))]
	public static class RecalculateSoulmatesPatch2
	{
		[HarmonyPostfix]
		[HarmonyPatch("Light_Rpc")]
		public static void LightPostfix(Campfire __instance)
		{
			Plugin.Log.LogInfo((object)"Campfire function");
			RecalculateSoulmatesEvent? recalculateSoulmatesEvent = Plugin.RecalculateSoulmate(firstTime: false);
			if (recalculateSoulmatesEvent.HasValue)
			{
				Events.SendRecalculateSoulmateEvent(recalculateSoulmatesEvent.Value);
			}
		}
	}
	public static class Extensions
	{
		public static bool isAbsolute(this STATUSTYPE t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)t != 7)
			{
				return (int)t == 9;
			}
			return true;
		}

		public static bool isShared(this STATUSTYPE t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			return (int)t != 5;
		}

		public static bool isLiv(this Character c)
		{
			if (!c.data.dead)
			{
				return !c.warping;
			}
			return false;
		}
	}
	public static class Soulmates
	{
		private static HashSet<string> globalSoulmates = new HashSet<string>();

		public static Dictionary<string, int> soulmateSets = new Dictionary<string, int>();

		public static HashSet<int> SoulmateNumbers()
		{
			Dictionary<string, Player> ps = PhotonNetwork.PlayerList.ToDictionary((Player p) => p.NickName);
			HashSet<int> hashSet = new HashSet<int>();
			foreach (int item in from sn in globalSoulmates
				select (!ps.ContainsKey(sn)) ? (-1) : ps[sn].ActorNumber into n
				where n != -1
				select n)
			{
				hashSet.Add(item);
			}
			return hashSet;
		}

		public static bool ActorIsSoulmate(int actor)
		{
			return SoulmateNumbers().Contains(actor);
		}

		public static void SetGlobalSoulmates(HashSet<string> s)
		{
			globalSoulmates = s;
		}

		public static bool NoSoulmates()
		{
			return globalSoulmates.Count == 0;
		}

		public static string SoulmateLog()
		{
			return string.Join(", ", globalSoulmates);
		}

		public static string SoulmateText()
		{
			if (NoSoulmates())
			{
				return "Soulmate: None";
			}
			if (globalSoulmates.Count == 1)
			{
				return "Soulmate: " + globalSoulmates.First();
			}
			return "Soulmates:\n" + string.Join("\n", globalSoulmates);
		}

		public static int LiveSoulmateCount()
		{
			return SoulmateNumbers().Count(delegate(int n)
			{
				Character soulmate = Plugin.GetSoulmate(n);
				return (Object)(object)soulmate != (Object)null && soulmate.isLiv();
			});
		}

		public static List<Character> SoulmateCharacters()
		{
			return (from n in SoulmateNumbers()
				select Plugin.GetSoulmate(n) into c
				where (Object)(object)c != (Object)null
				select c).ToList();
		}
	}
	[BepInPlugin("com.github.Wesmania.Soulmates", "Soulmates", "0.2.7")]
	public class Plugin : BaseUnityPlugin
	{
		internal const byte SHARED_DAMAGE_EVENT_CODE = 198;

		public static RecalculateSoulmatesEvent? previousSoulmates;

		public const string Id = "com.github.Wesmania.Soulmates";

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<bool> Enabled { get; private set; }

		internal static ConfigEntry<int> SoulmateGroupSize { get; private set; }

		internal static ConfigEntry<float> SoulmateStrength { get; private set; }

		internal static ConfigEntry<bool> EnableSharedBonk { get; private set; }

		internal static ConfigEntry<bool> EnableSharedSlip { get; private set; }

		internal static ConfigEntry<bool> EnableSharedExtraStaminaGain { get; private set; }

		internal static ConfigEntry<bool> EnableSharedExtraStaminaUse { get; private set; }

		internal static ConfigEntry<bool> EnableSharedLolli { get; private set; }

		internal static ConfigEntry<bool> EnableSharedEnergol { get; private set; }

		public static string Name => "Soulmates";

		public static string Version => "0.2.7";

		private void Awake()
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)("Plugin " + Name + " version 0.2.7 is loaded!"));
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "Enabled", true, "Enable/disable the mod with this");
			SoulmateGroupSize = ((BaseUnityPlugin)this).Config.Bind<int>("Config", "SoulmateGroupSize", 2, "How many people are bound in one group. Defaults to 2.");
			SoulmateStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Config", "SoulmateStrength", 1f, "How much of soulmate's status is applied to you");
			EnableSharedBonk = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSharedBonk", true, "Bonking a player bonks his soulmate too");
			EnableSharedSlip = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSharedSlip", true, "Slipping on something makes the soulmate slip too");
			EnableSharedExtraStaminaGain = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSharedExtraStaminaGain", true, "Soulmates share extra stamina gained");
			EnableSharedExtraStaminaUse = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSharedExtraStaminaUse", true, "Soulmates use a single extra stamina pool");
			EnableSharedLolli = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSharedLolli", true, "Soulmates share lollipop boost");
			EnableSharedEnergol = ((BaseUnityPlugin)this).Config.Bind<bool>("Config", "EnableSharedEnergol", true, "Soulmates share energy drink boost");
			if (!Enabled.Value)
			{
				Log.LogInfo((object)"Soulmates disabled");
				return;
			}
			PhotonNetwork.NetworkingClient.EventReceived += OnEvent;
			Harmony val = new Harmony("com.github.Wesmania.Soulmates");
			try
			{
				val.PatchAll();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to load mod: {arg}");
			}
		}

		private void OnDestroy()
		{
			if (Enabled.Value && PhotonNetwork.NetworkingClient != null)
			{
				PhotonNetwork.NetworkingClient.EventReceived -= OnEvent;
			}
		}

		public static int GetSoulmateGroupSize()
		{
			if (!previousSoulmates.HasValue)
			{
				return SoulmateGroupSize.Value;
			}
			return previousSoulmates.Value.config.soulmateGroupSize;
		}

		public static float GetSoulmateStrength()
		{
			if (!previousSoulmates.HasValue)
			{
				return SoulmateStrength.Value;
			}
			return previousSoulmates.Value.config.soulmateStrength;
		}

		public static bool localCharIsReady()
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || !localCharacter.isLiv())
			{
				return false;
			}
			return true;
		}

		public static string indexToNick(int idx)
		{
			Player val = PhotonNetwork.PlayerList.ToList().Find((Player p) => p.ActorNumber == idx);
			if (val == null)
			{
				return "";
			}
			return val.NickName;
		}

		private void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code == 198)
			{
				object[] array = (object[])photonEvent.CustomData;
				switch ((int)array[0])
				{
				case 0:
					OnRecalculateSoulmateEvent(photonEvent);
					break;
				case 1:
					OnSharedDamageEvent(photonEvent);
					break;
				case 2:
					Weight.OnUpdateWeightEvent(photonEvent);
					break;
				case 4:
					Bonk.OnSharedBonkEvent(photonEvent);
					break;
				case 5:
					StamUtil.OnSharedExtraStaminaEvent(photonEvent);
					break;
				case 6:
					AfflictionUtil.onSharedAfflictionEvent(photonEvent);
					break;
				case 7:
					TellMeMySoulmate.OnWhoIsMySoulmate(photonEvent);
					break;
				case 3:
					break;
				}
			}
		}

		private void OnSharedDamageEvent(EventData photonEvent)
		{
			//IL_0039: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_0114: 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)
			object[] array = (object[])photonEvent.CustomData;
			SharedDamage sharedDamage = SharedDamage.Deserialize((string)array[1]);
			int sender = photonEvent.Sender;
			if (!localCharIsReady())
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (!Soulmates.ActorIsSoulmate(sender))
			{
				return;
			}
			if (!sharedDamage.type.isShared())
			{
				Log.LogInfo((object)$"Received update for non-shared damage type {sharedDamage.type}");
				return;
			}
			if (sharedDamage.type.isAbsolute())
			{
				Log.LogInfo((object)$"Received an update request for an absolute damage type {sharedDamage.type}");
				return;
			}
			SharedDamagePatch.isReceivingSharedDamage.Add(((MonoBehaviourPun)localCharacter).photonView.ViewID);
			CharacterAfflictions afflictions = localCharacter.refs.afflictions;
			sharedDamage.value *= GetSoulmateStrength();
			try
			{
				switch (sharedDamage.kind)
				{
				case SharedDamageKind.ADD:
					afflictions.AddStatus(sharedDamage.type, sharedDamage.value, false, true);
					break;
				case SharedDamageKind.SUBTRACT:
					afflictions.SubtractStatus(sharedDamage.type, sharedDamage.value, false, false);
					break;
				case SharedDamageKind.SET:
				{
					float currentStatus = afflictions.GetCurrentStatus(sharedDamage.type);
					afflictions.SetStatus(sharedDamage.type, currentStatus + sharedDamage.value, true);
					break;
				}
				}
			}
			finally
			{
				SharedDamagePatch.isReceivingSharedDamage.Remove(((MonoBehaviourPun)localCharacter).photonView.ViewID);
			}
		}

		private static HashSet<string> findSoulmates(List<int> soulmates)
		{
			List<int> soulmates2 = soulmates;
			int groupSize = GetSoulmateGroupSize();
			Soulmates.soulmateSets = soulmates2.Select((int id, int idx) => (id, idx / groupSize)).ToDictionary<(int, int), string, int>(((int id, int) p) => indexToNick(p.id), ((int id, int) p) => p.Item2);
			int my_actor = PhotonNetwork.LocalPlayer.ActorNumber;
			int pos = soulmates2.FindIndex((int x) => x == my_actor);
			if (pos == -1)
			{
				Log.LogInfo((object)$"Did not find myself ({my_actor}) on soulmate list!");
				return new HashSet<string>();
			}
			Log.LogInfo((object)$"Found my index: {pos}");
			int start = pos - pos % groupSize;
			List<int> list = (from i in Enumerable.Range(start, groupSize)
				where i != pos && i < soulmates2.Count
				select i).ToList();
			Log.LogInfo((object)string.Format($"Soulmate group size: {list.Count + 1}"));
			return list.Select((int i) => indexToNick(soulmates2[i])).ToHashSet();
		}

		public static Character? GetSoulmate(int actor)
		{
			try
			{
				return Character.AllCharacters.Find((Character c) => ((MonoBehaviourPun)c).photonView.Owner.ActorNumber == actor);
			}
			catch (Exception)
			{
				return null;
			}
		}

		private static void ConnectToNewSoulmate(RecalculateSoulmatesEvent e)
		{
			if (localCharIsReady())
			{
				Character localCharacter = Character.localCharacter;
				int actorNumber = ((MonoBehaviourPun)localCharacter).photonView.Owner.ActorNumber;
				localCharacter.refs.afflictions.UpdateWeight();
			}
		}

		private static void OnRecalculateSoulmateEvent(EventData photonEvent)
		{
			Log.LogInfo((object)"Received recalculate soulmate event");
			object[] array = (object[])photonEvent.CustomData;
			RecalculateSoulmatesEvent recalculateSoulmatesEvent = RecalculateSoulmatesEvent.Deserialize((string)array[1]);
			previousSoulmates = recalculateSoulmatesEvent;
			Soulmates.SetGlobalSoulmates(findSoulmates(recalculateSoulmatesEvent.soulmates));
			if (Soulmates.NoSoulmates())
			{
				Log.LogInfo((object)"No soulmates");
			}
			else
			{
				Log.LogInfo((object)("New soulmates: " + Soulmates.SoulmateLog()));
			}
			if (recalculateSoulmatesEvent.firstTime)
			{
				Weight.Clear();
			}
			else
			{
				ConnectToNewSoulmate(recalculateSoulmatesEvent);
			}
			SoulmateTextPatch.SetSoulmateText(delay: (!recalculateSoulmatesEvent.firstTime) ? 15 : 10, text: Soulmates.SoulmateText());
		}

		public static RecalculateSoulmatesEvent? RecalculateSoulmate(bool firstTime)
		{
			Log.LogInfo((object)"Recalculating soulmate");
			Log.LogInfo((object)$"Character count: {PhotonNetwork.PlayerList.Count()}");
			List<int> list = PhotonNetwork.PlayerList.Select((Player x) => x.ActorNumber).ToList();
			list.Sort();
			string text = string.Join(" ", PhotonNetwork.PlayerList.Select((Player x) => ((object)x).ToString()));
			Log.LogInfo((object)("Characters: " + text));
			if (!PhotonNetwork.IsMasterClient)
			{
				return null;
			}
			Log.LogInfo((object)"I am master client, preparing new soulmate list");
			ExtCollections.Shuffle<int>((IList<int>)list);
			RecalculateSoulmatesEvent value = default(RecalculateSoulmatesEvent);
			value.soulmates = list;
			value.firstTime = firstTime;
			if (firstTime)
			{
				previousSoulmates = null;
			}
			if (previousSoulmates.HasValue)
			{
				value.config = previousSoulmates.Value.config;
			}
			else
			{
				value.config.sharedBonk = EnableSharedBonk.Value;
				value.config.sharedSlip = EnableSharedSlip.Value;
				value.config.sharedExtraStaminaGain = EnableSharedExtraStaminaGain.Value;
				value.config.sharedExtraStaminaUse = EnableSharedExtraStaminaUse.Value;
				value.config.sharedLolli = EnableSharedLolli.Value;
				value.config.sharedEnergol = EnableSharedEnergol.Value;
				value.config.soulmateGroupSize = SoulmateGroupSize.Value;
				value.config.soulmateStrength = SoulmateStrength.Value;
			}
			return value;
		}
	}
	[HarmonyPatch(typeof(SlipperyJellyfish))]
	public static class SlipPatch1
	{
		[HarmonyPrefix]
		[HarmonyPatch("OnTriggerEnter", new Type[] { typeof(Collider) })]
		public static void OnTriggerEnterPrefix(SlipperyJellyfish __instance, Collider other)
		{
			if (Plugin.previousSoulmates.HasValue && Plugin.previousSoulmates.Value.config.sharedSlip && !(__instance.counter < 3f))
			{
				Character componentInParent = ((Component)other).GetComponentInParent<Character>();
				int actor = (Object.op_Implicit((Object)(object)componentInParent) ? ((MonoBehaviourPun)componentInParent).photonView.Owner.ActorNumber : (-1));
				if (Object.op_Implicit((Object)(object)componentInParent) && Soulmates.ActorIsSoulmate(actor))
				{
					__instance.counter = 0f;
					__instance.relay.view.RPC("RPCA_TriggerWithTarget", (RpcTarget)0, new object[2]
					{
						((Component)__instance).transform.GetSiblingIndex(),
						Character.localCharacter.refs.view.ViewID
					});
				}
			}
		}
	}
	[HarmonyPatch(typeof(BananaPeel))]
	public static class SlipPatch2
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		public static void UpdatePrefix(BananaPeel __instance)
		{
			//IL_0041: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.previousSoulmates.HasValue || !Plugin.previousSoulmates.Value.config.sharedSlip)
			{
				return;
			}
			foreach (Character item in Soulmates.SoulmateCharacters())
			{
				if ((int)__instance.item.itemState == 0)
				{
					__instance.counter += Time.deltaTime;
					if (!(__instance.counter < 3f) && !(Vector3.Distance(item.Center, ((Component)__instance).transform.position) > 1f) && item.data.isGrounded && !(((Vector3)(ref item.data.avarageVelocity)).magnitude < 1.5f))
					{
						__instance.counter = 0f;
						((Component)__instance).GetComponent<PhotonView>().RPC("RPCA_TriggerBanana", (RpcTarget)0, new object[1] { Character.localCharacter.refs.view.ViewID });
					}
				}
			}
		}
	}
	[HarmonyPatch(typeof(UIPlayerNames))]
	public class SoulmateNickPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("UpdateName", new Type[]
		{
			typeof(int),
			typeof(Vector3),
			typeof(bool),
			typeof(int)
		})]
		public static void UpdateNamePostfix(UIPlayerNames __instance, int index, Vector3 position, bool visible, int speakingAmplitude)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Character.localCharacter) || index >= __instance.playerNameText.Length)
			{
				return;
			}
			Character character = __instance.playerNameText[index].characterInteractable.character;
			int actorNumber = ((MonoBehaviourPun)character).photonView.Owner.ActorNumber;
			TextMeshProUGUI text = __instance.playerNameText[index].text;
			if (Soulmates.ActorIsSoulmate(actorNumber))
			{
				((Graphic)text).color = Colors.soulmateColor;
				return;
			}
			string nickName = ((MonoBehaviourPun)character).photonView.Owner.NickName;
			if (!Soulmates.soulmateSets.ContainsKey(nickName))
			{
				((Graphic)text).color = Color.white;
				return;
			}
			int idx = Soulmates.soulmateSets[nickName];
			((Graphic)text).color = Colors.getColor(idx);
		}
	}
	[HarmonyPatch(typeof(GUIManager))]
	public static class SoulmateTextPatch
	{
		public static Canvas? SoulmatePrompt;

		public static TextMeshProUGUI? text;

		public static TMP_FontAsset? darumaDropOneFont;

		public static TextSetter? text_setter;

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void StartPostfix(GUIManager __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00d6: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)__instance).transform;
			GameObject val = new GameObject("SoulmatePrompt");
			val.transform.SetParent(transform, false);
			SoulmatePrompt = val.AddComponent<Canvas>();
			SoulmatePrompt.renderMode = (RenderMode)1;
			CanvasScaler val2 = ((Component)SoulmatePrompt).gameObject.GetComponent<CanvasScaler>() ?? ((Component)SoulmatePrompt).gameObject.AddComponent<CanvasScaler>();
			val2.referencePixelsPerUnit = 100f;
			val2.matchWidthOrHeight = 1f;
			val2.referenceResolution = new Vector2(1920f, 1080f);
			val2.scaleFactor = 1f;
			val2.screenMatchMode = (ScreenMatchMode)0;
			val2.uiScaleMode = (ScaleMode)1;
			GameObject val3 = new GameObject("TextChat");
			val3.transform.SetParent(((Component)SoulmatePrompt).transform, false);
			text = val3.AddComponent<TextMeshProUGUI>();
			RectTransform component = ((Component)text).GetComponent<RectTransform>();
			Vector2 sizeDelta = component.sizeDelta;
			sizeDelta.x *= 2f;
			component.sizeDelta = sizeDelta;
			text_setter = val3.AddComponent<TextSetter>();
			try
			{
				GUIManager instance = GUIManager.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					TextMeshProUGUI itemPromptDrop = instance.itemPromptDrop;
					obj = ((itemPromptDrop != null) ? ((TMP_Text)itemPromptDrop).font : null);
				}
				darumaDropOneFont = (TMP_FontAsset?)obj;
			}
			catch
			{
			}
			((TMP_Text)text).text = "";
			if ((Object)(object)darumaDropOneFont != (Object)null)
			{
				((TMP_Text)text).font = darumaDropOneFont;
			}
			((TMP_Text)text).horizontalAlignment = (HorizontalAlignmentOptions)2;
		}

		public static void SetSoulmateText(string text, float delay)
		{
			if ((Object)(object)text_setter != (Object)null)
			{
				text_setter.SetSoulmateText(text, delay);
			}
		}
	}
	public class TextSetter : MonoBehaviour
	{
		public void SetSoulmateText(string text, float delay)
		{
			string text2 = text;
			Plugin.Log.LogInfo((object)"In SetSoulmateText");
			((MonoBehaviour)this).StartCoroutine(TextCoroutine());
			IEnumerator TextCoroutine()
			{
				Plugin.Log.LogInfo((object)"In SetSoulmateText coroutine");
				yield return (object)new WaitForSeconds(delay);
				if ((Object)(object)SoulmateTextPatch.text != (Object)null)
				{
					Plugin.Log.LogInfo((object)"In SetSoulmateText coroutine, set text");
					((TMP_Text)SoulmateTextPatch.text).text = text2;
				}
				yield return (object)new WaitForSeconds(10f);
				if ((Object)(object)SoulmateTextPatch.text != (Object)null)
				{
					Plugin.Log.LogInfo((object)"In SetSoulmateText coroutine, reset text");
					((TMP_Text)SoulmateTextPatch.text).text = "";
				}
				Plugin.Log.LogInfo((object)"In SetSoulmateText coroutine end");
			}
		}
	}
	[Serializable]
	public struct Config
	{
		public bool sharedBonk;

		public bool sharedSlip;

		public bool sharedExtraStaminaGain;

		public bool sharedExtraStaminaUse;

		public bool sharedLolli;

		public bool sharedEnergol;

		public int soulmateGroupSize;

		public float soulmateStrength;
	}
	[Serializable]
	public struct RecalculateSoulmatesEvent
	{
		public Config config;

		public List<int> soulmates;

		public bool firstTime;

		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static RecalculateSoulmatesEvent Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<RecalculateSoulmatesEvent>(s);
		}
	}
	[Serializable]
	public enum SharedDamageKind
	{
		ADD,
		SUBTRACT,
		SET
	}
	[Serializable]
	public struct SharedDamage
	{
		public STATUSTYPE type;

		public float value;

		public SharedDamageKind kind;

		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static SharedDamage Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<SharedDamage>(s);
		}
	}
	[Serializable]
	public struct UpdateWeight
	{
		public float weight;

		public float thorns;

		public UpdateWeight()
		{
			weight = 0f;
			thorns = 0f;
		}

		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static UpdateWeight Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<UpdateWeight>(s);
		}
	}
	[Serializable]
	public struct V3
	{
		public float x;

		public float y;

		public float z;

		public V3(Vector3 v)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			x = v.x;
			y = v.y;
			z = v.z;
		}

		public Vector3 toVector3()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(x, y, z);
		}
	}
	[Serializable]
	public struct SharedBonk
	{
		public int victim;

		public float ragdollTime;

		public V3 force;

		public V3 contactPoint;

		public float range;

		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static SharedBonk Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<SharedBonk>(s);
		}
	}
	public struct SharedExtraStamina
	{
		public float diff;

		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static SharedExtraStamina Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<SharedExtraStamina>(s);
		}
	}
	public struct SharedAffliction
	{
		public AfflictionType type;

		public float totalTime;

		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static SharedAffliction Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<SharedAffliction>(s);
		}
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct WhoIsMySoulmate
	{
		public string Serialize()
		{
			return JsonConvert.SerializeObject((object)this);
		}

		public static WhoIsMySoulmate Deserialize(string s)
		{
			return JsonConvert.DeserializeObject<WhoIsMySoulmate>(s);
		}
	}
	internal enum SoulmateEventType
	{
		RECALCULATE = 0,
		DAMAGE = 1,
		UPDATE_WEIGHT = 2,
		SHARED_BONK = 4,
		SHARED_EXTRA_STAMINA = 5,
		SHARED_AFFLICTION = 6,
		WHO_IS_MY_SOULMATES = 7
	}
	public static class Weight
	{
		private static Dictionary<int, UpdateWeight> playerWeights = new Dictionary<int, UpdateWeight>();

		public static bool shouldSendWeight;

		public static void Clear()
		{
			playerWeights.Clear();
			shouldSendWeight = false;
		}

		private static bool updateLocalWeightAndCheckIfChanged(UpdateWeight w)
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return false;
			}
			int actorNumber = ((MonoBehaviourPun)localCharacter).photonView.Owner.ActorNumber;
			if (!playerWeights.ContainsKey(actorNumber))
			{
				playerWeights[actorNumber] = w;
				return true;
			}
			UpdateWeight updateWeight = playerWeights[actorNumber];
			playerWeights[actorNumber] = w;
			if (updateWeight.weight == w.weight)
			{
				return updateWeight.thorns != w.thorns;
			}
			return true;
		}

		public static UpdateWeight getLocalWeight()
		{
			UpdateWeight result = default(UpdateWeight);
			result.weight = 0f;
			result.thorns = 0f;
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return result;
			}
			int actorNumber = ((MonoBehaviourPun)localCharacter).photonView.Owner.ActorNumber;
			if (!playerWeights.ContainsKey(actorNumber))
			{
				return result;
			}
			return playerWeights[actorNumber];
		}

		public static void OnUpdateWeightEvent(EventData photonEvent)
		{
			object[] array = (object[])photonEvent.CustomData;
			UpdateWeight value = UpdateWeight.Deserialize((string)array[1]);
			int sender = photonEvent.Sender;
			playerWeights[sender] = value;
			if (Soulmates.ActorIsSoulmate(sender) && Plugin.localCharIsReady())
			{
				Character.localCharacter.refs.afflictions.UpdateWeight();
			}
		}

		public static UpdateWeight RecalculateSharedWeight(UpdateWeight original)
		{
			if (!Plugin.localCharIsReady())
			{
				return original;
			}
			Character localCharacter = Character.localCharacter;
			CharacterAfflictions afflictions = localCharacter.refs.afflictions;
			List<Character> list = Soulmates.SoulmateCharacters();
			float num = list.Count;
			UpdateWeight updateWeight = default(UpdateWeight);
			updateWeight.weight = 0f;
			updateWeight.thorns = 0f;
			foreach (Character item in list)
			{
				if (item.isLiv() && playerWeights.ContainsKey(((MonoBehaviourPun)item).photonView.Owner.ActorNumber))
				{
					updateWeight.weight += playerWeights[((MonoBehaviourPun)item).photonView.Owner.ActorNumber].weight;
					updateWeight.thorns += playerWeights[((MonoBehaviourPun)item).photonView.Owner.ActorNumber].thorns;
				}
			}
			float soulmateStrength = Plugin.GetSoulmateStrength();
			original.weight = (original.weight + updateWeight.weight * soulmateStrength) / (soulmateStrength * num + 1f);
			original.thorns += updateWeight.thorns * soulmateStrength;
			return original;
		}

		private static bool ShouldSendWeight()
		{
			bool result = shouldSendWeight;
			shouldSendWeight = false;
			return result;
		}

		public static void MaybeSendWeight()
		{
			if (ShouldSendWeight())
			{
				UpdateWeight localWeight = getLocalWeight();
				Events.SendUpdateWeightEvent(localWeight);
			}
		}

		public static float PreSetWeight(CharacterAfflictions c, STATUSTYPE kind, float value)
		{
			//IL_000f: 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_0021: Invalid comparison between Unknown and I4
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			if (!c.character.IsLocal)
			{
				return value;
			}
			if (!kind.isAbsolute())
			{
				return value;
			}
			UpdateWeight localWeight = getLocalWeight();
			if ((int)kind == 7)
			{
				localWeight.weight = value;
			}
			else
			{
				localWeight.thorns = value;
			}
			if (updateLocalWeightAndCheckIfChanged(localWeight))
			{
				shouldSendWeight = true;
			}
			localWeight = RecalculateSharedWeight(localWeight);
			if ((int)kind == 7)
			{
				return localWeight.weight;
			}
			return localWeight.thorns;
		}
	}
	internal class TellMeMySoulmate
	{
		public static void OnWhoIsMySoulmate(EventData photonEvent)
		{
			object[] array = (object[])photonEvent.CustomData;
			WhoIsMySoulmate whoIsMySoulmate = WhoIsMySoulmate.Deserialize((string)array[1]);
			int sender = photonEvent.Sender;
			if (PhotonNetwork.IsMasterClient && Plugin.previousSoulmates.HasValue)
			{
				Events.SendThisIsYourSoulmatesEvent(Plugin.previousSoulmates.Value, sender);
			}
		}
	}
	[HarmonyPatch(typeof(NetworkConnector))]
	internal class WhoIsMySoulmatePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("OnJoinedRoom")]
		public static void OnJoinedRoomPostfix(ReconnectHandler __instance)
		{
			if (!Plugin.previousSoulmates.HasValue)
			{
				Events.SendWhoIsMySoulmatesEvent();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}