Decompiled source of MwSkinAdditions v1.0.0

MwSkinAdditions.dll

Decompiled 3 hours 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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using EntityStates.Missions.BrotherEncounter;
using HG;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.EntityStates;
using On.EntityStates.Missions.BrotherEncounter;
using On.RoR2;
using R2API.Networking;
using R2API.Networking.Interfaces;
using RoR2;
using RoR2.Audio;
using RoR2.ContentManagement;
using UnityEngine;
using UnityEngine.Networking;

[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("MwSkinAdditions")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2daef9410be75371974365d52b883266dd6bfe6c")]
[assembly: AssemblyProduct("MwSkinAdditions")]
[assembly: AssemblyTitle("MwSkinAdditions")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MwSkinAdditions
{
	public class BlendShapeAnimation
	{
		public string meshName;

		public string blendShapeName;

		public int feature;

		public int priority;

		public float fadeInDuration;

		public float holdDuration;

		public float fadeOutDuration;

		public bool blockBlinking;

		public BlendShapeAnimation(string meshName, string blendShapeName, int feature, int priority, float fadeInDuration, float holdDuration, float fadeOutDuration, bool blockBlinking = false)
		{
			this.meshName = meshName;
			this.blendShapeName = blendShapeName;
			this.feature = feature;
			this.priority = priority;
			this.fadeInDuration = fadeInDuration;
			this.holdDuration = holdDuration;
			this.fadeOutDuration = fadeOutDuration;
			this.blockBlinking = blockBlinking;
		}
	}
	public class BlinkBlendShapeAnimation : BlendShapeAnimation
	{
		public BlinkBlendShapeAnimation(string meshName, string blendShapeName, int feature = -1, int priority = 0, float fadeInDuration = 0.1f, float holdDuration = 0f, float fadeOutDuration = 0.1f, bool blockBlinking = false)
			: base(meshName, blendShapeName, feature, priority, fadeInDuration, holdDuration, fadeOutDuration, blockBlinking)
		{
		}
	}
	public class BoneTransformation
	{
		public string armaturePath;

		public Vector3 localScale;

		public Vector3 position;

		public string relativeBonePath;

		public BoneTransformation(string armaturePath, Vector3 localScale, Vector3 localPosition, string relativeBonePath = null)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			this.armaturePath = armaturePath;
			this.localScale = localScale;
			position = localPosition;
			this.relativeBonePath = relativeBonePath;
		}
	}
	internal class ContentPacks : IContentPackProvider
	{
		[CompilerGenerated]
		private sealed class <FinalizeAsync>d__9 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public FinalizeAsyncArgs args;

			public ContentPacks <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <FinalizeAsync>d__9(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				args.ReportProgress(1f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <GenerateContentPackAsync>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public GetContentPackAsyncArgs args;

			public ContentPacks <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GenerateContentPackAsync>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				ContentPack.Copy(<>4__this.contentPack, args.output);
				args.ReportProgress(1f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <LoadStaticContentAsync>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public LoadStaticContentAsyncArgs args;

			public ContentPacks <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <LoadStaticContentAsync>d__7(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				if (<>1__state != 0)
				{
					return false;
				}
				<>1__state = -1;
				<>4__this.contentPack.identifier = <>4__this.identifier;
				<>4__this.contentPack.networkSoundEventDefs.Add(networkSoundEventDefs.ToArray());
				args.ReportProgress(1f);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		internal ContentPack contentPack = new ContentPack();

		public static List<NetworkSoundEventDef> networkSoundEventDefs = new List<NetworkSoundEventDef>();

		public string identifier => "mwmw.MwSkinAdditions";

		internal static NetworkSoundEventDef CreateAndAddNetworkSoundEventDef(string eventName)
		{
			NetworkSoundEventDef val = ScriptableObject.CreateInstance<NetworkSoundEventDef>();
			val.akId = AkSoundEngine.GetIDFromString(eventName);
			val.eventName = eventName;
			networkSoundEventDefs.Add(val);
			return val;
		}

		public void Initialize()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(ContentManager_collectContentPackProviders);
		}

		private void ContentManager_collectContentPackProviders(AddContentPackProviderDelegate addContentPackProvider)
		{
			addContentPackProvider.Invoke((IContentPackProvider)(object)this);
		}

		[IteratorStateMachine(typeof(<LoadStaticContentAsync>d__7))]
		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <LoadStaticContentAsync>d__7(0)
			{
				<>4__this = this,
				args = args
			};
		}

		[IteratorStateMachine(typeof(<GenerateContentPackAsync>d__8))]
		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <GenerateContentPackAsync>d__8(0)
			{
				<>4__this = this,
				args = args
			};
		}

		[IteratorStateMachine(typeof(<FinalizeAsync>d__9))]
		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <FinalizeAsync>d__9(0)
			{
				<>4__this = this,
				args = args
			};
		}
	}
	public class EventSub
	{
		public SkinDef skinDef;

		public BoneTransformation[] boneTransformations;

		public ExtraObject[] extraObjects;

		public bool useAnimations = false;

		public BlendShapeAnimation[] blinkAnimations;

		public IdleAnimation[] conditionalIdleAnimations;

		public VoiceGroup[] voiceGroups;

		public static Action<GameObject> DifferentSkinAppliedGlobal;

		public Action<GameObject> SkinAppliedLobby;

		public Action<GameObject> SkinAppliedRun;

		public Action<GameObject, DamageReport> TakeDamage;

		public Action<GameObject> Death;

		public Action<GameObject> DefeatBossGroup;

		public Action<GameObject> LeavePod;

		public Action<GameObject> UsePrimary;

		public Action<GameObject> UseSecondary;

		public Action<GameObject> UseUtility;

		public Action<GameObject> UseSpecial;

		public Action<GameObject> ShrineSuccess;

		public Action<GameObject> ShrineFailure;

		public Action<GameObject> TeleporterStart;

		public Action<GameObject> TeleporterEnd;

		public Action<GameObject> BearDamageBlock;

		public Action<GameObject> LevelUp;

		public Action<GameObject> MithrixDefeat;

		public Action<GameObject> UseEquipment;

		public Action<GameObject, float> Heal;

		public Action<GameObject> Jump;

		public Action<GameObject> LeaveStage;

		public Action<GameObject> Idle;

		public Action<GameObject, ItemIndex> GetItem;

		public Action<GameObject> HoldoutZoneCharged;

		public EventSub(SkinDef skinDef, BoneTransformation[] boneTransformations = null, ExtraObject[] extraObjects = null, bool useAnimations = false, BlendShapeAnimation[] blinkAnimations = null, IdleAnimation[] conditionalIdleAnimations = null, VoiceGroup[] voiceGroups = null)
		{
			this.skinDef = skinDef;
			this.boneTransformations = boneTransformations;
			this.extraObjects = extraObjects;
			this.useAnimations = useAnimations;
			this.blinkAnimations = blinkAnimations;
			this.conditionalIdleAnimations = conditionalIdleAnimations;
			this.voiceGroups = voiceGroups;
		}

		public void Init()
		{
			SkinEvents.SubscribeEventSkin(this);
			if (boneTransformations != null)
			{
				SubscribeTransformEvents();
			}
			if (extraObjects != null)
			{
				SubscribeExtraObjectEvents();
			}
			if (useAnimations)
			{
				SubscribeAnimationEvents();
			}
			if (voiceGroups != null)
			{
				SubscribeVoiceEvents();
			}
		}

		private void SubscribeTransformEvents()
		{
			SkinAppliedRun = (Action<GameObject>)Delegate.Combine(SkinAppliedRun, new Action<GameObject>(AddTransformController));
			SkinAppliedLobby = (Action<GameObject>)Delegate.Combine(SkinAppliedLobby, new Action<GameObject>(AddTransformController));
			Death = (Action<GameObject>)Delegate.Combine(Death, new Action<GameObject>(DisableTransformController));
		}

		private void AddTransformController(GameObject body)
		{
			TransformController transformController = body.GetComponent<TransformController>();
			if ((Object)(object)transformController == (Object)null)
			{
				transformController = body.AddComponent<TransformController>();
			}
			transformController.Init(this);
		}

		public void DisableTransformController(GameObject body)
		{
			TransformController transformController = ((body != null) ? body.GetComponent<TransformController>() : null);
			if ((Object)(object)transformController != (Object)null)
			{
				((Behaviour)transformController).enabled = false;
			}
		}

		private void SubscribeExtraObjectEvents()
		{
			SkinAppliedRun = (Action<GameObject>)Delegate.Combine(SkinAppliedRun, new Action<GameObject>(AddExtraObjects));
			SkinAppliedLobby = (Action<GameObject>)Delegate.Combine(SkinAppliedLobby, new Action<GameObject>(AddExtraObjects));
		}

		private void AddExtraObjects(GameObject body)
		{
			//IL_0057: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = SkinEvents.GetModelFromEventBody(body).transform;
			ExtraObjectController extraObjectController = body.AddComponent<ExtraObjectController>();
			ExtraObject[] array = extraObjects;
			foreach (ExtraObject extraObject in array)
			{
				GameObject val = Object.Instantiate<GameObject>(extraObject.prefab);
				val.transform.parent = transform.Find(extraObject.armatureParentPath);
				val.transform.localPosition = extraObject.localPosition;
				val.transform.localEulerAngles = extraObject.localEulerAngles;
				val.transform.localScale = extraObject.localScale;
				extraObjectController.extraObjs.Add(val);
			}
		}

		private void SubscribeAnimationEvents()
		{
			SkinAppliedRun = (Action<GameObject>)Delegate.Combine(SkinAppliedRun, new Action<GameObject>(AddExpressionController));
			SkinAppliedLobby = (Action<GameObject>)Delegate.Combine(SkinAppliedLobby, new Action<GameObject>(AddExpressionController));
		}

		private void AddExpressionController(GameObject body)
		{
			ExpressionController expressionController = body.GetComponent<ExpressionController>();
			if ((Object)(object)expressionController == (Object)null)
			{
				expressionController = body.AddComponent<ExpressionController>();
			}
			expressionController.Init(this);
		}

		private void SubscribeVoiceEvents()
		{
			SkinAppliedRun = (Action<GameObject>)Delegate.Combine(SkinAppliedRun, new Action<GameObject>(AddVoiceController));
			SkinAppliedLobby = (Action<GameObject>)Delegate.Combine(SkinAppliedLobby, new Action<GameObject>(AddVoiceController));
		}

		private void AddVoiceController(GameObject body)
		{
			VoiceController voiceController = body.GetComponent<VoiceController>();
			if ((Object)(object)voiceController == (Object)null)
			{
				voiceController = body.AddComponent<VoiceController>();
			}
			voiceController.Init(this);
		}
	}
	public class ExpressionController : MonoBehaviour
	{
		private class ExpressionState
		{
			public Coroutine coroutine;

			public BlendShapeAnimation animation;

			public SkinnedMeshRenderer skinnedMeshRenderer;

			public bool finished;
		}

		[CompilerGenerated]
		private sealed class <BlendToZero>d__21 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public ExpressionState expressionState;

			public ExpressionController <>4__this;

			private int <index>5__1;

			private float <startWeight>5__2;

			private float <stopwatch>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <BlendToZero>d__21(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<index>5__1 = <>4__this.GetBlendShapeIndex(expressionState.animation, expressionState.skinnedMeshRenderer);
					<startWeight>5__2 = expressionState.skinnedMeshRenderer.GetBlendShapeWeight(<index>5__1);
					<stopwatch>5__3 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<stopwatch>5__3 < expressionState.animation.fadeOutDuration)
				{
					<stopwatch>5__3 += Time.deltaTime;
					expressionState.skinnedMeshRenderer.SetBlendShapeWeight(<index>5__1, Mathf.Lerp(<startWeight>5__2, 0f, <stopwatch>5__3 / expressionState.animation.fadeOutDuration));
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <ExpressionRoutine>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public BlendShapeAnimation animation;

			public SkinnedMeshRenderer renderer;

			public ExpressionState expressionState;

			public ExpressionController <>4__this;

			private float <stopwatch>5__1;

			private int <index>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ExpressionRoutine>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_0123: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<stopwatch>5__1 = 0f;
					<>4__this.featureActive[animation.feature] = true;
					<index>5__2 = <>4__this.GetBlendShapeIndex(animation, renderer);
					goto IL_00df;
				case 1:
					<>1__state = -1;
					goto IL_00df;
				case 2:
					<>1__state = -1;
					<stopwatch>5__1 = 0f;
					break;
				case 3:
					{
						<>1__state = -1;
						break;
					}
					IL_00df:
					if (<stopwatch>5__1 < animation.fadeInDuration)
					{
						<stopwatch>5__1 += Time.deltaTime;
						renderer.SetBlendShapeWeight(<index>5__2, Mathf.Lerp(0f, 100f, <stopwatch>5__1 / animation.fadeInDuration));
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					renderer.SetBlendShapeWeight(<index>5__2, 100f);
					<>2__current = (object)new WaitForSeconds(animation.holdDuration);
					<>1__state = 2;
					return true;
				}
				if (<stopwatch>5__1 < animation.fadeOutDuration)
				{
					<stopwatch>5__1 += Time.deltaTime;
					renderer.SetBlendShapeWeight(<index>5__2, Mathf.Lerp(100f, 0f, <stopwatch>5__1 / animation.fadeOutDuration));
					<>2__current = null;
					<>1__state = 3;
					return true;
				}
				renderer.SetBlendShapeWeight(<index>5__2, 0f);
				<>4__this.featureActive[animation.feature] = false;
				if (animation.blockBlinking)
				{
					<>4__this.blinkStoppers--;
				}
				expressionState.finished = true;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private EventSub eventSub;

		private CharacterBody cachedCharacterBody;

		private Dictionary<string, SkinnedMeshRenderer> cachedRenderers = new Dictionary<string, SkinnedMeshRenderer>();

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

		private Dictionary<int, ExpressionState> featureStates = new Dictionary<int, ExpressionState>();

		private Dictionary<int, bool> featureActive = new Dictionary<int, bool>();

		public bool inDeathState;

		private float blinkInterval;

		private float blinkStopwatch;

		private bool doubleBlink;

		private int blinkStoppers;

		public CharacterBody characterBody
		{
			get
			{
				if ((Object)(object)cachedCharacterBody != (Object)null)
				{
					return cachedCharacterBody;
				}
				cachedCharacterBody = ((Component)this).GetComponent<CharacterBody>();
				return cachedCharacterBody;
			}
		}

		public void Init(EventSub eventSub)
		{
			this.eventSub = eventSub;
			eventSub.Death = (Action<GameObject>)Delegate.Combine(eventSub.Death, (Action<GameObject>)delegate
			{
				inDeathState = true;
			});
		}

		public void TryPlayAnimation(BlendShapeAnimation animation)
		{
			SkinnedMeshRenderer skinnedMeshRenderer = GetSkinnedMeshRenderer(animation.meshName);
			if ((Object)(object)skinnedMeshRenderer != (Object)null)
			{
				TrySetExpressionRoutine(animation, skinnedMeshRenderer);
			}
		}

		private SkinnedMeshRenderer GetSkinnedMeshRenderer(string meshName)
		{
			if (cachedRenderers.ContainsKey(meshName))
			{
				SkinnedMeshRenderer val = cachedRenderers[meshName];
				if (val != null)
				{
					return val;
				}
			}
			GameObject modelFromEventBody = SkinEvents.GetModelFromEventBody(((Component)this).gameObject);
			object obj;
			if (modelFromEventBody == null)
			{
				obj = null;
			}
			else
			{
				Transform obj2 = modelFromEventBody.transform.Find(meshName);
				obj = ((obj2 != null) ? ((Component)obj2).GetComponent<SkinnedMeshRenderer>() : null);
			}
			SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)obj;
			cachedRenderers[meshName] = val2;
			return val2;
		}

		private void TrySetExpressionRoutine(BlendShapeAnimation animation, SkinnedMeshRenderer renderer)
		{
			ExpressionState featureState = GetFeatureState(animation.feature);
			if (featureState != null && animation.priority > featureState.animation.priority)
			{
				CancelExpression(featureState);
			}
			if (!GetFeatureActive(animation.feature))
			{
				ExpressionState expressionState = new ExpressionState
				{
					animation = animation,
					skinnedMeshRenderer = renderer
				};
				expressionState.coroutine = ((MonoBehaviour)this).StartCoroutine(ExpressionRoutine(animation, renderer, expressionState));
				featureStates[animation.feature] = expressionState;
				if (animation.blockBlinking)
				{
					blinkStoppers++;
				}
			}
		}

		[IteratorStateMachine(typeof(<ExpressionRoutine>d__18))]
		private IEnumerator ExpressionRoutine(BlendShapeAnimation animation, SkinnedMeshRenderer renderer, ExpressionState expressionState)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ExpressionRoutine>d__18(0)
			{
				<>4__this = this,
				animation = animation,
				renderer = renderer,
				expressionState = expressionState
			};
		}

		public void CancelCurrentExpressions()
		{
			foreach (ExpressionState value in featureStates.Values)
			{
				if (value != null)
				{
					CancelExpression(value);
				}
			}
		}

		private void CancelExpression(ExpressionState expressionState)
		{
			((MonoBehaviour)this).StopCoroutine(expressionState.coroutine);
			featureActive[expressionState.animation.feature] = false;
			((MonoBehaviour)this).StartCoroutine(BlendToZero(expressionState));
			if (!expressionState.finished && expressionState.animation.blockBlinking)
			{
				blinkStoppers--;
				expressionState.finished = true;
			}
		}

		[IteratorStateMachine(typeof(<BlendToZero>d__21))]
		private IEnumerator BlendToZero(ExpressionState expressionState)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <BlendToZero>d__21(0)
			{
				<>4__this = this,
				expressionState = expressionState
			};
		}

		private ExpressionState GetFeatureState(int feature)
		{
			if (featureStates.ContainsKey(feature))
			{
				return featureStates[feature];
			}
			return null;
		}

		private bool GetFeatureActive(int feature)
		{
			if (featureActive.ContainsKey(feature))
			{
				return featureActive[feature];
			}
			return false;
		}

		private int GetBlendShapeIndex(BlendShapeAnimation animation, SkinnedMeshRenderer skinnedMeshRenderer)
		{
			if (cachedBlendShapes.ContainsKey(animation.blendShapeName))
			{
				return cachedBlendShapes[animation.blendShapeName];
			}
			int blendShapeIndex = skinnedMeshRenderer.sharedMesh.GetBlendShapeIndex(animation.blendShapeName);
			cachedBlendShapes[animation.blendShapeName] = blendShapeIndex;
			return blendShapeIndex;
		}

		private void Update()
		{
			if (eventSub.blinkAnimations != null && blinkStoppers <= 0)
			{
				BlinkUpdate();
			}
			if (eventSub.conditionalIdleAnimations != null)
			{
				IdleUpdate();
			}
		}

		private void BlinkUpdate()
		{
			blinkStopwatch += Time.deltaTime;
			if (!(blinkStopwatch >= blinkInterval))
			{
				return;
			}
			if (!inDeathState)
			{
				BlendShapeAnimation[] blinkAnimations = eventSub.blinkAnimations;
				foreach (BlendShapeAnimation animation in blinkAnimations)
				{
					TryPlayAnimation(animation);
				}
				if (doubleBlink)
				{
					doubleBlink = false;
				}
				else if (Random.value <= 0.1f)
				{
					doubleBlink = true;
				}
			}
			else
			{
				doubleBlink = false;
			}
			blinkStopwatch = 0f;
			if (doubleBlink)
			{
				blinkInterval = 0.3f;
			}
			else
			{
				blinkInterval = Random.Range(3f, 8f);
			}
		}

		private void IdleUpdate()
		{
			IdleAnimation[] conditionalIdleAnimations = eventSub.conditionalIdleAnimations;
			foreach (IdleAnimation idleAnimation in conditionalIdleAnimations)
			{
				if (idleAnimation == null || idleAnimation.condition == null)
				{
					continue;
				}
				if (idleAnimation.condition(this))
				{
					BlendShapeAnimation[] animations = idleAnimation.animations;
					foreach (BlendShapeAnimation animation in animations)
					{
						TryPlayAnimation(animation);
					}
				}
				else
				{
					if (!idleAnimation.cancelOnConditionFalse)
					{
						continue;
					}
					BlendShapeAnimation[] animations2 = idleAnimation.animations;
					foreach (BlendShapeAnimation blendShapeAnimation in animations2)
					{
						ExpressionState featureState = GetFeatureState(blendShapeAnimation.feature);
						if (GetFeatureActive(blendShapeAnimation.feature) && featureState?.animation == blendShapeAnimation)
						{
							CancelExpression(featureState);
						}
					}
				}
			}
		}
	}
	public class ExtraObject
	{
		public GameObject prefab;

		public string armatureParentPath;

		public Vector3 localScale;

		public Vector3 localPosition;

		public Vector3 localEulerAngles;

		public ExtraObject(GameObject prefab, string armatureParentPath, Vector3 localScale, Vector3 localPosition, Vector3 localEulerAngles)
		{
			//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_001e: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			this.prefab = prefab;
			this.armatureParentPath = armatureParentPath;
			this.localScale = localScale;
			this.localPosition = localPosition;
			this.localEulerAngles = localEulerAngles;
		}
	}
	public class ExtraObjectController : MonoBehaviour
	{
		public List<GameObject> extraObjs;

		public void Awake()
		{
			extraObjs = new List<GameObject>();
		}
	}
	public class IdleAnimation
	{
		public BlendShapeAnimation[] animations;

		public Func<ExpressionController, bool> condition;

		public bool cancelOnConditionFalse;

		public IdleAnimation(BlendShapeAnimation[] animations, Func<ExpressionController, bool> condition, bool cancelOnConditionFalse = true)
		{
			this.animations = animations;
			this.condition = condition;
			this.cancelOnConditionFalse = cancelOnConditionFalse;
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("mwmw.MwSkinAdditions", "MwSkinAdditions", "1.0.0")]
	public class MwSkinAdditions : BaseUnityPlugin
	{
		public const string PluginGUID = "mwmw.MwSkinAdditions";

		public const string PluginAuthor = "mwmw";

		public const string PluginName = "MwSkinAdditions";

		public const string PluginVersion = "1.0.0";

		public static PluginInfo pluginInfo;

		public static MwSkinAdditions instance;

		public void Awake()
		{
			instance = this;
			pluginInfo = ((BaseUnityPlugin)this).Info;
			Log.Init(((BaseUnityPlugin)this).Logger);
			SkinEvents.Init();
			RoR2Application.onStart = (Action)Delegate.Combine(RoR2Application.onStart, (Action)delegate
			{
				new ContentPacks().Initialize();
			});
		}
	}
	public static class MwUtils
	{
		[CompilerGenerated]
		private sealed class <ExecuteWhenNearPosition>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Action action;

			public GameObject gameObject;

			public Vector3 position;

			public float maxWait;

			private float <stopwatch>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ExecuteWhenNearPosition>d__4(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0063: 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)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<stopwatch>5__1 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (Vector3.Distance(gameObject.transform.position, position) > 0.5f && <stopwatch>5__1 < maxWait)
				{
					<stopwatch>5__1 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				action?.Invoke();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public static Random rand = new Random();

		public static object RandomChoices(IEnumerable<object> choices, IEnumerable<float> weights)
		{
			List<float> list = new List<float>();
			float num = 0f;
			foreach (float weight in weights)
			{
				num += weight;
				list.Add(num);
			}
			float num2 = (float)rand.NextDouble() * num;
			int num3 = 0;
			foreach (object choice in choices)
			{
				if (num2 <= list[num3])
				{
					return choice;
				}
				num3++;
			}
			Log.Warning("RandomChoices: Couldn't make a choice - returning null!");
			return null;
		}

		public static object RandomChoice(IEnumerable<object> choices)
		{
			IList<object> list = (choices as IList<object>) ?? choices.ToList();
			if (list.Count > 0)
			{
				return list[rand.Next(list.Count)];
			}
			Log.Warning("RandomChoice: Got passed an empty enumerable - returning null!");
			return null;
		}

		public static object RandomChoice(object[] choices)
		{
			if (choices.Length != 0)
			{
				return choices[rand.Next(choices.Length)];
			}
			Log.Warning("RandomChoice: Got passed an empty enumerable - returning null!");
			return null;
		}

		[IteratorStateMachine(typeof(<ExecuteWhenNearPosition>d__4))]
		public static IEnumerator ExecuteWhenNearPosition(Action action, GameObject gameObject, Vector3 position, float maxWait = 1f)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ExecuteWhenNearPosition>d__4(0)
			{
				action = action,
				gameObject = gameObject,
				position = position,
				maxWait = maxWait
			};
		}
	}
	public static class SkinEvents
	{
		public class SyncGetItem : INetMessage, ISerializableObject
		{
			private NetworkInstanceId netInstanceId;

			private int itemIndex;

			public SyncGetItem()
			{
			}

			public SyncGetItem(NetworkInstanceId netInstanceId, int itemIndex)
			{
				//IL_0009: 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)
				this.netInstanceId = netInstanceId;
				this.itemIndex = itemIndex;
			}

			public void Serialize(NetworkWriter writer)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				writer.Write(netInstanceId);
				writer.Write(itemIndex);
			}

			public void Deserialize(NetworkReader reader)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				netInstanceId = reader.ReadNetworkId();
				itemIndex = reader.ReadInt32();
			}

			public void OnReceived()
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Util.FindNetworkObject(netInstanceId);
				if ((Object)(object)val != (Object)null)
				{
					InvokeGetItem(val, itemIndex);
				}
			}
		}

		public class SyncUseShrine : INetMessage, ISerializableObject
		{
			private NetworkInstanceId netInstanceId;

			private bool success;

			public SyncUseShrine()
			{
			}

			public SyncUseShrine(NetworkInstanceId netInstanceId, bool success)
			{
				//IL_0009: 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)
				this.netInstanceId = netInstanceId;
				this.success = success;
			}

			public void Serialize(NetworkWriter writer)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				writer.Write(netInstanceId);
				writer.Write(success);
			}

			public void Deserialize(NetworkReader reader)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				netInstanceId = reader.ReadNetworkId();
				success = reader.ReadBoolean();
			}

			public void OnReceived()
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Util.FindNetworkObject(netInstanceId);
				if ((Object)(object)val != (Object)null)
				{
					InvokeUseShrine(val, success);
				}
			}
		}

		public class SyncHoldoutZoneCharged : INetMessage, ISerializableObject
		{
			public void Serialize(NetworkWriter writer)
			{
			}

			public void Deserialize(NetworkReader reader)
			{
			}

			public void OnReceived()
			{
				InvokeHoldoutZoneCharged();
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static hook_ApplySkinAsync <0>__OnSkinAppliedBody;

			public static hook_OnInteractionBegin <1>__OnTeleporterStart;

			public static hook_OnDeathStart <2>__OnDeath;

			public static hook_EjectPassenger_GameObject <3>__OnLeavePod;

			public static hook_OnSkillActivated <4>__OnSkillActivated;

			public static hook_AddShrineStack <5>__OnChanceShrineInteract;

			public static Manipulator <6>__OnPickupAttemptGrant;

			public static Manipulator <7>__OnBearDamageBlock;

			public static Action<BossGroup> <8>__OnDefeatBossGroup;

			public static Action<TeleporterInteraction> <9>__OnTeleporterEnd;

			public static Action<DamageReport> <10>__OnTakeDamage;

			public static Action<CharacterBody> <11>__OnLevelUp;

			public static hook_OnEnter <12>__OnMithrixDefeat;

			public static Action<EquipmentSlot, EquipmentIndex> <13>__OnUseEquipment;

			public static Action<HealthComponent, float, ProcChainMask> <14>__OnHeal;

			public static hook_ApplyJumpVelocity <15>__OnJump;

			public static hook_Begin <16>__OnLeaveStage;

			public static hook_Update <17>__OnBodyUpdate;

			public static Action<GameObject> <18>__RemoveTransformController;

			public static Action<GameObject> <19>__RemoveExtraObjects;

			public static Action<GameObject> <20>__RemoveVoiceController;

			public static Action<GameObject> <21>__RemoveExpressionController;
		}

		[CompilerGenerated]
		private sealed class <HoldBodyFromIdleUpdate>d__32 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CharacterBody body;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <HoldBodyFromIdleUpdate>d__32(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					holdOffIdleInvocation?.Add(body);
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					holdOffIdleInvocation?.Remove(body);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <OnSkinAppliedBody>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public orig_ApplySkinAsync orig;

			public ModelSkinController self;

			public int skinIndex;

			public AsyncReferenceHandleUnloadType unloadType;

			private GameObject <bodyObject>5__1;

			private EventSub <bodyEventSub>5__2;

			private SkinDef <skinDef>5__3;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <OnSkinAppliedBody>d__8(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<bodyObject>5__1 = null;
				<bodyEventSub>5__2 = null;
				<skinDef>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = orig.Invoke(self, skinIndex, unloadType);
					<>1__state = 1;
					return true;
				case 1:
					{
						<>1__state = -1;
						ModelSkinController obj = self;
						object obj2;
						if (obj == null)
						{
							obj2 = null;
						}
						else
						{
							CharacterModel characterModel = obj.characterModel;
							if (characterModel == null)
							{
								obj2 = null;
							}
							else
							{
								CharacterBody body = characterModel.body;
								obj2 = ((body != null) ? ((Component)body).gameObject : null);
							}
						}
						<bodyObject>5__1 = (GameObject)obj2;
						<bodyEventSub>5__2 = null;
						if ((Object)(object)<bodyObject>5__1 != (Object)null)
						{
							<bodyEventSub>5__2 = GetEventSubFromBody(<bodyObject>5__1);
						}
						if ((Object)(object)<bodyObject>5__1 != (Object)null && <bodyEventSub>5__2 != null)
						{
							<bodyEventSub>5__2.SkinAppliedRun?.Invoke(<bodyObject>5__1);
							goto IL_01c6;
						}
						if ((Object)(object)<bodyObject>5__1 == (Object)null)
						{
							<skinDef>5__3 = ArrayUtils.GetSafe<SkinDef>(self.skins, self.currentSkinIndex);
							if (<skinDef>5__3 != null && skinDefToEventSub.ContainsKey(<skinDef>5__3))
							{
								<bodyEventSub>5__2 = GetEventSubFromSkinDef(<skinDef>5__3);
								<bodyEventSub>5__2.SkinAppliedLobby?.Invoke(((Component)self).gameObject);
								goto IL_01bf;
							}
						}
						if ((Object)(object)<bodyObject>5__1 != (Object)null)
						{
							EventSub.DifferentSkinAppliedGlobal?.Invoke(<bodyObject>5__1);
						}
						else
						{
							EventSub.DifferentSkinAppliedGlobal?.Invoke(((Component)self).gameObject);
						}
						goto IL_01bf;
					}
					IL_01c6:
					return false;
					IL_01bf:
					<skinDef>5__3 = null;
					goto IL_01c6;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static Dictionary<SkinDef, EventSub> skinDefToEventSub = new Dictionary<SkinDef, EventSub>();

		public static HashSet<CharacterBody> holdOffIdleInvocation = new HashSet<CharacterBody>();

		public static void Init()
		{
			SubscribeGameEvents();
			SubscribeGlobalEvents();
		}

		public static void SubscribeEventSkin(EventSub eventSkin)
		{
			skinDefToEventSub.Add(eventSkin.skinDef, eventSkin);
		}

		private static void SubscribeGameEvents()
		{
			//IL_0011: 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_001c: Expected O, but got Unknown
			//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_003d: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0074: 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_007f: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00b6: 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_00c1: Expected O, but got Unknown
			//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_00e2: Expected O, but got Unknown
			//IL_00f8: 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_0103: Expected O, but got Unknown
			//IL_019d: 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_01a8: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Expected O, but got Unknown
			object obj = <>O.<0>__OnSkinAppliedBody;
			if (obj == null)
			{
				hook_ApplySkinAsync val = OnSkinAppliedBody;
				<>O.<0>__OnSkinAppliedBody = val;
				obj = (object)val;
			}
			ModelSkinController.ApplySkinAsync += (hook_ApplySkinAsync)obj;
			object obj2 = <>O.<1>__OnTeleporterStart;
			if (obj2 == null)
			{
				hook_OnInteractionBegin val2 = OnTeleporterStart;
				<>O.<1>__OnTeleporterStart = val2;
				obj2 = (object)val2;
			}
			TeleporterInteraction.OnInteractionBegin += (hook_OnInteractionBegin)obj2;
			object obj3 = <>O.<2>__OnDeath;
			if (obj3 == null)
			{
				hook_OnDeathStart val3 = OnDeath;
				<>O.<2>__OnDeath = val3;
				obj3 = (object)val3;
			}
			CharacterBody.OnDeathStart += (hook_OnDeathStart)obj3;
			object obj4 = <>O.<3>__OnLeavePod;
			if (obj4 == null)
			{
				hook_EjectPassenger_GameObject val4 = OnLeavePod;
				<>O.<3>__OnLeavePod = val4;
				obj4 = (object)val4;
			}
			VehicleSeat.EjectPassenger_GameObject += (hook_EjectPassenger_GameObject)obj4;
			object obj5 = <>O.<4>__OnSkillActivated;
			if (obj5 == null)
			{
				hook_OnSkillActivated val5 = OnSkillActivated;
				<>O.<4>__OnSkillActivated = val5;
				obj5 = (object)val5;
			}
			CharacterBody.OnSkillActivated += (hook_OnSkillActivated)obj5;
			object obj6 = <>O.<5>__OnChanceShrineInteract;
			if (obj6 == null)
			{
				hook_AddShrineStack val6 = OnChanceShrineInteract;
				<>O.<5>__OnChanceShrineInteract = val6;
				obj6 = (object)val6;
			}
			ShrineChanceBehavior.AddShrineStack += (hook_AddShrineStack)obj6;
			object obj7 = <>O.<6>__OnPickupAttemptGrant;
			if (obj7 == null)
			{
				Manipulator val7 = OnPickupAttemptGrant;
				<>O.<6>__OnPickupAttemptGrant = val7;
				obj7 = (object)val7;
			}
			GenericPickupController.AttemptGrant += (Manipulator)obj7;
			object obj8 = <>O.<7>__OnBearDamageBlock;
			if (obj8 == null)
			{
				Manipulator val8 = OnBearDamageBlock;
				<>O.<7>__OnBearDamageBlock = val8;
				obj8 = (object)val8;
			}
			HealthComponent.TakeDamageProcess += (Manipulator)obj8;
			BossGroup.onBossGroupDefeatedServer += OnDefeatBossGroup;
			TeleporterInteraction.onTeleporterChargedGlobal += OnTeleporterEnd;
			GlobalEventManager.onServerDamageDealt += OnTakeDamage;
			GlobalEventManager.onCharacterLevelUp += OnLevelUp;
			object obj9 = <>O.<12>__OnMithrixDefeat;
			if (obj9 == null)
			{
				hook_OnEnter val9 = OnMithrixDefeat;
				<>O.<12>__OnMithrixDefeat = val9;
				obj9 = (object)val9;
			}
			EncounterFinished.OnEnter += (hook_OnEnter)obj9;
			EquipmentSlot.onServerEquipmentActivated += OnUseEquipment;
			HealthComponent.onCharacterHealServer += OnHeal;
			object obj10 = <>O.<15>__OnJump;
			if (obj10 == null)
			{
				hook_ApplyJumpVelocity val10 = OnJump;
				<>O.<15>__OnJump = val10;
				obj10 = (object)val10;
			}
			GenericCharacterMain.ApplyJumpVelocity += (hook_ApplyJumpVelocity)obj10;
			object obj11 = <>O.<16>__OnLeaveStage;
			if (obj11 == null)
			{
				hook_Begin val11 = OnLeaveStage;
				<>O.<16>__OnLeaveStage = val11;
				obj11 = (object)val11;
			}
			SceneExitController.Begin += (hook_Begin)obj11;
			object obj12 = <>O.<17>__OnBodyUpdate;
			if (obj12 == null)
			{
				hook_Update val12 = OnBodyUpdate;
				<>O.<17>__OnBodyUpdate = val12;
				obj12 = (object)val12;
			}
			CharacterBody.Update += (hook_Update)obj12;
		}

		public static void SubscribeGlobalEvents()
		{
			EventSub.DifferentSkinAppliedGlobal = (Action<GameObject>)Delegate.Combine(EventSub.DifferentSkinAppliedGlobal, new Action<GameObject>(RemoveTransformController));
			EventSub.DifferentSkinAppliedGlobal = (Action<GameObject>)Delegate.Combine(EventSub.DifferentSkinAppliedGlobal, new Action<GameObject>(RemoveExtraObjects));
			EventSub.DifferentSkinAppliedGlobal = (Action<GameObject>)Delegate.Combine(EventSub.DifferentSkinAppliedGlobal, new Action<GameObject>(RemoveVoiceController));
			EventSub.DifferentSkinAppliedGlobal = (Action<GameObject>)Delegate.Combine(EventSub.DifferentSkinAppliedGlobal, new Action<GameObject>(RemoveExpressionController));
		}

		public static EventSub GetEventSubFromBody(GameObject body)
		{
			try
			{
				SkinDef skinDef = SkinCatalog.FindCurrentSkinDefForBodyInstance(body);
				return GetEventSubFromSkinDef(skinDef);
			}
			catch (NullReferenceException)
			{
				Log.Error("GetEventSubFromBody NRE! Returning null...");
				return null;
			}
		}

		public static EventSub GetEventSubFromSkinDef(SkinDef skinDef)
		{
			if ((Object)(object)skinDef == (Object)null || !skinDefToEventSub.ContainsKey(skinDef))
			{
				return null;
			}
			return skinDefToEventSub[skinDef];
		}

		[IteratorStateMachine(typeof(<OnSkinAppliedBody>d__8))]
		private static IEnumerator OnSkinAppliedBody(orig_ApplySkinAsync orig, ModelSkinController self, int skinIndex, AsyncReferenceHandleUnloadType unloadType)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <OnSkinAppliedBody>d__8(0)
			{
				orig = orig,
				self = self,
				skinIndex = skinIndex,
				unloadType = unloadType
			};
		}

		private static void OnTeleporterStart(orig_OnInteractionBegin orig, TeleporterInteraction self, Interactor activator)
		{
			orig.Invoke(self, activator);
			TeleporterInteraction instance = TeleporterInteraction.instance;
			if (instance != null && !instance.isCharged)
			{
				GetEventSubFromBody(((Component)activator).gameObject)?.TeleporterStart?.Invoke(((Component)activator).gameObject);
			}
		}

		private static void OnDeath(orig_OnDeathStart orig, CharacterBody self)
		{
			orig.Invoke(self);
			GetEventSubFromBody(((Component)self).gameObject)?.Death?.Invoke(((Component)self).gameObject);
		}

		private static void OnLeavePod(orig_EjectPassenger_GameObject orig, VehicleSeat self, GameObject body)
		{
			orig.Invoke(self, body);
			if (self.isSurvivorPod)
			{
				GetEventSubFromBody(body)?.LeavePod?.Invoke(body);
			}
		}

		private static void OnSkillActivated(orig_OnSkillActivated orig, CharacterBody self, GenericSkill skill)
		{
			orig.Invoke(self, skill);
			EventSub eventSubFromBody = GetEventSubFromBody(((Component)self).gameObject);
			if (eventSubFromBody != null)
			{
				if ((Object)(object)skill == (Object)(object)self.skillLocator.primary)
				{
					eventSubFromBody.UsePrimary?.Invoke(((Component)self).gameObject);
				}
				else if ((Object)(object)skill == (Object)(object)self.skillLocator.secondary)
				{
					eventSubFromBody.UseSecondary?.Invoke(((Component)self).gameObject);
				}
				else if ((Object)(object)skill == (Object)(object)self.skillLocator.utility)
				{
					eventSubFromBody.UseUtility?.Invoke(((Component)self).gameObject);
				}
				else if ((Object)(object)skill == (Object)(object)self.skillLocator.special)
				{
					eventSubFromBody.UseSpecial?.Invoke(((Component)self).gameObject);
				}
			}
		}

		private static void OnChanceShrineInteract(orig_AddShrineStack orig, ShrineChanceBehavior self, Interactor activator)
		{
			int successfulPurchaseCount = self.successfulPurchaseCount;
			orig.Invoke(self, activator);
			EventSub eventSubFromBody = GetEventSubFromBody(((Component)self).gameObject);
			if (eventSubFromBody != null)
			{
				if (successfulPurchaseCount < self.successfulPurchaseCount)
				{
					eventSubFromBody.ShrineSuccess?.Invoke(((Component)activator).gameObject);
				}
				else
				{
					eventSubFromBody.ShrineFailure?.Invoke(((Component)activator).gameObject);
				}
			}
		}

		private static void OnBearDamageBlock(ILContext il)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			Action<HealthComponent> action = delegate(HealthComponent healthComponent)
			{
				GetEventSubFromBody(((Component)healthComponent.body).gameObject)?.BearDamageBlock?.Invoke(((Component)healthComponent.body).gameObject);
			};
			ILCursor val = new ILCursor(il);
			int num4 = default(int);
			int num3 = default(int);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.HealthComponent+AssetReferences", "bearEffectPrefab")
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num4)
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, ref num3)
			}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "RoR2.EffectManager", "SpawnEffect")
			}))
			{
				val.Emit(OpCodes.Ldarg_0);
				val.EmitDelegate<Action<HealthComponent>>(action);
				int num2 = default(int);
				int num = default(int);
				if (val.TryGotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, "RoR2.HealthComponent+AssetReferences", "bearVoidEffectPrefab")
				}) && val.TryGotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref num2)
				}) && val.TryGotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, ref num)
				}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, "RoR2.EffectManager", "SpawnEffect")
				}))
				{
					val.Emit(OpCodes.Ldarg_0);
					val.EmitDelegate<Action<HealthComponent>>(action);
				}
			}
			else
			{
				Log.Error("OnBearDamageBlock ILHook failed. Tougher Times/Safer Spaces block events will not occur");
			}
		}

		private static void OnLevelUp(CharacterBody characterBody)
		{
			GameObject val = ((characterBody != null) ? ((Component)characterBody).gameObject : null);
			GetEventSubFromBody(val)?.LevelUp?.Invoke(val);
		}

		private static void OnPickupAttemptGrant(ILContext il)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Action<CharacterBody, PickupDef> action = delegate(CharacterBody body, PickupDef pickupDef)
			{
				//IL_001c: 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_002c: Expected I4, but got Unknown
				EventSub eventSubFromBody = GetEventSubFromBody(((Component)body).gameObject);
				if (eventSubFromBody != null)
				{
					NetMessageExtensions.Send((INetMessage)(object)new SyncGetItem(body.master.bodyInstanceId, (int)pickupDef.itemIndex), (NetworkDestination)1);
				}
			};
			ILCursor c = new ILCursor(il);
			int pickupLoc = 2;
			if (c.TryGotoNext(new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)typeof(PickupCatalog).GetMethod("GetPickupDef")),
				(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref pickupLoc)
			}) && c.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdfld<GrantContext>(x, "shouldDestroy") && c.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchStfld<GenericPickupController>(x, "consumed")
				})
			}))
			{
				c.Emit(OpCodes.Ldarg_1);
				c.Emit(OpCodes.Ldloc, pickupLoc);
				c.EmitDelegate<Action<CharacterBody, PickupDef>>(action);
			}
			else
			{
				Log.Error("OnPickupAttemptGrant ILHook failed. Pickup interaction related events will not occur");
			}
		}

		private static void OnDefeatBossGroup(BossGroup bossGroup)
		{
			if (!(((Object)((Component)bossGroup).gameObject).name != "BrotherEncounter, Phase 4"))
			{
				return;
			}
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				GameObject val = ((readOnlyInstances != null) ? readOnlyInstances.GetBodyObject() : null);
				if ((Object)(object)val != (Object)null)
				{
					GetEventSubFromBody(val)?.DefeatBossGroup?.Invoke(val);
				}
			}
		}

		private static void OnTeleporterEnd(TeleporterInteraction teleporterInteraction)
		{
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				GameObject val = ((readOnlyInstances != null) ? readOnlyInstances.GetBodyObject() : null);
				if ((Object)(object)val != (Object)null)
				{
					GetEventSubFromBody(val)?.TeleporterEnd?.Invoke(val);
				}
			}
		}

		private static void OnTakeDamage(DamageReport damageReport)
		{
			if (!((Object)(object)damageReport?.victimBody != (Object)null))
			{
				return;
			}
			object body;
			if (damageReport == null)
			{
				body = null;
			}
			else
			{
				CharacterBody victimBody = damageReport.victimBody;
				body = ((victimBody != null) ? ((Component)victimBody).gameObject : null);
			}
			EventSub eventSubFromBody = GetEventSubFromBody((GameObject)body);
			if (eventSubFromBody == null)
			{
				return;
			}
			Action<GameObject, DamageReport> takeDamage = eventSubFromBody.TakeDamage;
			if (takeDamage != null)
			{
				object arg;
				if (damageReport == null)
				{
					arg = null;
				}
				else
				{
					CharacterBody victimBody2 = damageReport.victimBody;
					arg = ((victimBody2 != null) ? ((Component)victimBody2).gameObject : null);
				}
				takeDamage((GameObject)arg, damageReport);
			}
		}

		private static void OnMithrixDefeat(orig_OnEnter orig, EncounterFinished self)
		{
			orig.Invoke(self);
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				GameObject val = ((readOnlyInstances != null) ? readOnlyInstances.GetBodyObject() : null);
				if ((Object)(object)val != (Object)null)
				{
					GetEventSubFromBody(val)?.MithrixDefeat?.Invoke(val);
				}
			}
		}

		private static void OnUseEquipment(EquipmentSlot self, EquipmentIndex index)
		{
			GetEventSubFromBody(((Component)self.characterBody).gameObject)?.UseEquipment?.Invoke(((Component)self.characterBody).gameObject);
		}

		private static void OnHeal(HealthComponent self, float amount, ProcChainMask procChainMaskn)
		{
			object obj;
			if (self == null)
			{
				obj = null;
			}
			else
			{
				CharacterBody body = self.body;
				obj = ((body != null) ? ((Component)body).gameObject : null);
			}
			GameObject val = (GameObject)obj;
			GetEventSubFromBody(val)?.Heal?.Invoke(val, amount);
		}

		private static void OnJump(orig_ApplyJumpVelocity orig, CharacterMotor characterMotor, CharacterBody characterBody, float horizontalBonus, float verticalBonus, bool vault)
		{
			orig.Invoke(characterMotor, characterBody, horizontalBonus, verticalBonus, vault);
			GetEventSubFromBody(((Component)characterBody).gameObject)?.Jump?.Invoke(((Component)characterBody).gameObject);
		}

		private static void OnLeaveStage(orig_Begin orig, SceneExitController self)
		{
			orig.Invoke(self);
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				GameObject val = ((readOnlyInstances != null) ? readOnlyInstances.GetBodyObject() : null);
				if ((Object)(object)val != (Object)null)
				{
					GetEventSubFromBody(val)?.LeaveStage?.Invoke(val);
				}
			}
		}

		public static GameObject GetModelFromEventBody(GameObject body)
		{
			if ((Object)(object)Run.instance != (Object)null && Object.op_Implicit((Object)(object)body))
			{
				ModelLocator component = body.GetComponent<ModelLocator>();
				object result;
				if (component == null)
				{
					result = null;
				}
				else
				{
					Transform modelTransform = component.modelTransform;
					result = ((modelTransform != null) ? ((Component)modelTransform).gameObject : null);
				}
				return (GameObject)result;
			}
			return body;
		}

		public static ExpressionController GetExpressionController(GameObject body)
		{
			GameObject modelFromEventBody = GetModelFromEventBody(body);
			return (modelFromEventBody != null) ? modelFromEventBody.GetComponent<ExpressionController>() : null;
		}

		public static void RemoveExtraObjects(GameObject body)
		{
			ExtraObjectController component = body.GetComponent<ExtraObjectController>();
			if (!((Object)(object)component != (Object)null))
			{
				return;
			}
			foreach (GameObject extraObj in component.extraObjs)
			{
				Object.Destroy((Object)(object)extraObj);
			}
			Object.Destroy((Object)(object)component);
		}

		public static void RemoveTransformController(GameObject body)
		{
			TransformController transformController = ((body != null) ? body.GetComponent<TransformController>() : null);
			if ((Object)(object)transformController != (Object)null)
			{
				Object.Destroy((Object)(object)transformController);
			}
		}

		public static void RemoveVoiceController(GameObject body)
		{
			VoiceController voiceController = ((body != null) ? body.GetComponent<VoiceController>() : null);
			if ((Object)(object)voiceController != (Object)null)
			{
				Object.Destroy((Object)(object)voiceController);
			}
		}

		public static void RemoveExpressionController(GameObject body)
		{
			ExpressionController expressionController = ((body != null) ? body.GetComponent<ExpressionController>() : null);
			if ((Object)(object)expressionController != (Object)null)
			{
				expressionController.CancelCurrentExpressions();
				Object.Destroy((Object)(object)expressionController);
			}
		}

		private static void OnBodyUpdate(orig_Update orig, CharacterBody self)
		{
			orig.Invoke(self);
			if (!((Object)(object)self == (Object)null) && self.notMovingStopwatch > 10f)
			{
				EventSub eventSubFromBody = GetEventSubFromBody(((Component)self).gameObject);
				if (eventSubFromBody != null && self.notMovingStopwatch % 10f < 0.1f && !holdOffIdleInvocation.Contains(self))
				{
					eventSubFromBody.Idle?.Invoke(((Component)self).gameObject);
					((MonoBehaviour)RoR2Application.instance).StartCoroutine(HoldBodyFromIdleUpdate(self));
				}
			}
		}

		[IteratorStateMachine(typeof(<HoldBodyFromIdleUpdate>d__32))]
		private static IEnumerator HoldBodyFromIdleUpdate(CharacterBody body)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <HoldBodyFromIdleUpdate>d__32(0)
			{
				body = body
			};
		}

		public static void InvokeGetItem(GameObject body, int itemIndex)
		{
			EventSub eventSubFromBody = GetEventSubFromBody(body.gameObject);
			eventSubFromBody.GetItem?.Invoke(body.gameObject, (ItemIndex)itemIndex);
		}

		public static void InvokeUseShrine(GameObject body, bool success)
		{
			EventSub eventSubFromBody = GetEventSubFromBody(body);
			if (success)
			{
				eventSubFromBody.ShrineSuccess?.Invoke(body);
			}
			else
			{
				eventSubFromBody.ShrineFailure?.Invoke(body);
			}
		}

		public static void InvokeHoldoutZoneCharged()
		{
			foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList)
			{
				GameObject val = ((readOnlyInstances != null) ? readOnlyInstances.GetBodyObject() : null);
				if ((Object)(object)val != (Object)null)
				{
					GetEventSubFromBody(val)?.HoldoutZoneCharged?.Invoke(val);
				}
			}
		}
	}
	public class TransformController : MonoBehaviour
	{
		private Transform[] boneTransforms;

		private Dictionary<Transform, Transform> boneRelativeTo = new Dictionary<Transform, Transform>();

		public BoneTransformation[] boneTransformations;

		public BoneTransformation rtiBoneTransformation;

		private int _rtiIndex = 0;

		private Vector3 _rtiPositionVector;

		private Vector3 _rtiLocalScaleVector;

		public int rtiIndex
		{
			get
			{
				return _rtiIndex;
			}
			set
			{
				//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_0033: 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)
				_rtiIndex = value;
				rtiBoneTransformation = boneTransformations[_rtiIndex];
				_rtiPositionVector = rtiBoneTransformation.position;
				_rtiLocalScaleVector = rtiBoneTransformation.localScale;
			}
		}

		public Vector3 rtiPositionVector
		{
			get
			{
				//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_000a: Unknown result type (might be due to invalid IL or missing references)
				return _rtiPositionVector;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				_rtiPositionVector = value;
				rtiBoneTransformation.position = _rtiPositionVector;
			}
		}

		public Vector3 rtiLocalScaleVector
		{
			get
			{
				//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_000a: Unknown result type (might be due to invalid IL or missing references)
				return _rtiLocalScaleVector;
			}
			set
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				_rtiLocalScaleVector = value;
				rtiBoneTransformation.localScale = _rtiLocalScaleVector;
			}
		}

		public void Init(EventSub eventSub)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			boneTransformations = eventSub.boneTransformations;
			rtiBoneTransformation = boneTransformations[rtiIndex];
			_rtiPositionVector = rtiBoneTransformation.position;
			_rtiLocalScaleVector = rtiBoneTransformation.localScale;
		}

		private void Start()
		{
			AssignLimbs();
		}

		private void AssignLimbs()
		{
			List<Transform> list = new List<Transform>();
			for (int i = 0; i < boneTransformations.Length; i++)
			{
				Transform val = SkinEvents.GetModelFromEventBody(((Component)this).gameObject).transform.Find(boneTransformations[i].armaturePath);
				if ((Object)(object)val != (Object)null)
				{
					list.Add(SkinEvents.GetModelFromEventBody(((Component)this).gameObject).transform.Find(boneTransformations[i].armaturePath));
					if (boneTransformations[i].relativeBonePath != null)
					{
						Transform val2 = SkinEvents.GetModelFromEventBody(((Component)this).gameObject).transform.Find(boneTransformations[i].relativeBonePath);
						if ((Object)(object)val2 != (Object)null)
						{
							boneRelativeTo[val] = val2;
							continue;
						}
						Log.Error("Received invalid relative bone path: " + boneTransformations[i].relativeBonePath);
						boneRelativeTo[val] = val;
					}
					else
					{
						boneRelativeTo[val] = val;
					}
				}
				else
				{
					Log.Error("Received invalid bone path: " + boneTransformations[i].armaturePath);
				}
			}
			boneTransforms = list.ToArray();
		}

		private void LateUpdate()
		{
			ApplyScale();
			ApplyPosition();
		}

		private void ApplyScale()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < boneTransforms.Length; i++)
			{
				boneTransforms[i].localScale = boneTransformations[i].localScale;
			}
		}

		private void ApplyPosition()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < boneTransforms.Length; i++)
			{
				Transform val = boneRelativeTo[boneTransforms[i]];
				boneTransforms[i].position = val.TransformPoint(boneTransformations[i].position);
			}
		}
	}
	public class VoiceArray
	{
		public VoiceInfo[] voiceLines;

		public VoiceGroup group;

		public VoiceArray(VoiceInfo[] voiceLines)
		{
			this.voiceLines = voiceLines;
		}
	}
	public class VoiceController : MonoBehaviour
	{
		private float timeSinceLastRolledLine;

		private const float soundWaitPadding = 0.5f;

		private float currentSoundWait;

		private Dictionary<VoiceGroup, float> voiceGroupStopwatches;

		private Dictionary<VoiceArray, int> lastPlayedIndex = new Dictionary<VoiceArray, int>();

		public void Init(EventSub eventSub)
		{
			voiceGroupStopwatches = new Dictionary<VoiceGroup, float>();
			VoiceGroup[] voiceGroups = eventSub.voiceGroups;
			foreach (VoiceGroup key in voiceGroups)
			{
				voiceGroupStopwatches.Add(key, 0f);
			}
		}

		private void Awake()
		{
			if (!NetworkServer.active)
			{
				Object.Destroy((Object)(object)this);
			}
		}

		private void Update()
		{
			float deltaTime = Time.deltaTime;
			VoiceGroup[] array = voiceGroupStopwatches.Keys.ToArray();
			foreach (VoiceGroup key in array)
			{
				voiceGroupStopwatches[key] += deltaTime;
			}
			timeSinceLastRolledLine += deltaTime;
		}

		public bool RollForSoundEvent(VoiceArray soundArray, float maxProbability = 1f)
		{
			if (timeSinceLastRolledLine < currentSoundWait)
			{
				return false;
			}
			float num = voiceGroupStopwatches[soundArray.group];
			float num2 = soundArray.group.maxWait - soundArray.group.minWait;
			float num3 = ((num2 != 0f) ? Mathf.Min(maxProbability, (num - soundArray.group.minWait) / num2) : 1f);
			if (num > soundArray.group.minWait && Random.value <= num3)
			{
				voiceGroupStopwatches[soundArray.group] = 0f;
				timeSinceLastRolledLine = 0f;
				return true;
			}
			return false;
		}

		public void TryPlayRandomUniqueSoundServer(VoiceArray soundArray, GameObject source, float maxProbability = 1f)
		{
			if (!NetworkServer.active || !RollForSoundEvent(soundArray, maxProbability))
			{
				return;
			}
			int num;
			if (lastPlayedIndex.ContainsKey(soundArray))
			{
				num = MwUtils.rand.Next(soundArray.voiceLines.Length - 1);
				if (num >= lastPlayedIndex[soundArray])
				{
					num++;
					num %= soundArray.voiceLines.Length;
				}
			}
			else
			{
				num = MwUtils.rand.Next(soundArray.voiceLines.Length);
				lastPlayedIndex.Add(soundArray, num);
			}
			lastPlayedIndex[soundArray] = num;
			PlaySoundServer(soundArray.voiceLines[num], source, this);
		}

		public void TryPlayRandomSoundServer(VoiceArray soundArray, GameObject source, float maxProbability = 1f)
		{
			if (NetworkServer.active && RollForSoundEvent(soundArray, maxProbability))
			{
				PlayRandomSoundServer(soundArray, source, this);
			}
		}

		public void TryPlayRandomSoundServer(VoiceArray soundArray, Vector3 position, float maxProbability = 1f)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && RollForSoundEvent(soundArray, maxProbability))
			{
				PlayRandomSoundServer(soundArray, position, this);
			}
		}

		public void TryPlayRandomSound(VoiceArray soundArray, GameObject source, float maxProbability = 1f)
		{
			if (RollForSoundEvent(soundArray, maxProbability))
			{
				PlayRandomSound(soundArray, source, this);
			}
		}

		public void TryPlayRandomSound(VoiceArray soundArray, Vector3 position, float maxProbability = 1f)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (RollForSoundEvent(soundArray, maxProbability))
			{
				PlayRandomSound(soundArray, position, this);
			}
		}

		public static void PlayRandomSoundServer(VoiceArray soundArray, GameObject source, VoiceController voiceController = null)
		{
			if (NetworkServer.active)
			{
				object[] voiceLines = soundArray.voiceLines;
				VoiceInfo voiceInfo = (VoiceInfo)MwUtils.RandomChoice(voiceLines);
				PlaySoundServer(voiceInfo, source, voiceController);
			}
		}

		public static void PlayRandomSoundServer(VoiceArray soundArray, Vector3 position, VoiceController voiceController = null)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				object[] voiceLines = soundArray.voiceLines;
				VoiceInfo voiceInfo = (VoiceInfo)MwUtils.RandomChoice(voiceLines);
				PlaySoundServer(voiceInfo, position, voiceController);
			}
		}

		public static void PlayRandomSound(VoiceArray soundArray, GameObject source, VoiceController voiceController = null)
		{
			object[] voiceLines = soundArray.voiceLines;
			VoiceInfo voiceInfo = (VoiceInfo)MwUtils.RandomChoice(voiceLines);
			PlaySound(voiceInfo, source, voiceController);
		}

		public static void PlayRandomSound(VoiceArray soundArray, Vector3 position, VoiceController voiceController = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			object[] voiceLines = soundArray.voiceLines;
			VoiceInfo voiceInfo = (VoiceInfo)MwUtils.RandomChoice(voiceLines);
			PlaySound(voiceInfo, position, voiceController);
		}

		public static void PlaySoundServer(VoiceInfo voiceInfo, GameObject source, VoiceController voiceController = null)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				EntitySoundManager.EmitSoundServer(AkEventIdArg.op_Implicit(voiceInfo.sound.akId), source);
				if ((Object)(object)voiceController != (Object)null)
				{
					voiceController.currentSoundWait = voiceInfo.approxDuration + 0.5f;
				}
			}
		}

		public static void PlaySoundServer(VoiceInfo voiceInfo, Vector3 position, VoiceController voiceController = null)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				EffectManager.SimpleSoundEffect(voiceInfo.sound.index, position, true);
				if ((Object)(object)voiceController != (Object)null)
				{
					voiceController.currentSoundWait = voiceInfo.approxDuration + 0.5f;
				}
			}
		}

		public static void PlaySound(VoiceInfo voiceInfo, GameObject source, VoiceController voiceController = null)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			EntitySoundManager.EmitSoundLocal(AkEventIdArg.op_Implicit(voiceInfo.sound.akId), source);
			if ((Object)(object)voiceController != (Object)null)
			{
				voiceController.currentSoundWait = voiceInfo.approxDuration + 0.5f;
			}
		}

		public static void PlaySound(VoiceInfo voiceInfo, Vector3 position, VoiceController voiceController = null)
		{
			//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)
			EffectManager.SimpleSoundEffect(voiceInfo.sound.index, position, false);
			if ((Object)(object)voiceController != (Object)null)
			{
				voiceController.currentSoundWait = voiceInfo.approxDuration + 0.5f;
			}
		}
	}
	public class VoiceGroup
	{
		public VoiceArray[] voiceArrays;

		public float minWait;

		public float maxWait;

		public VoiceGroup(VoiceArray[] voiceArrays, float minWait, float maxWait)
		{
			this.voiceArrays = voiceArrays;
			this.minWait = minWait;
			this.maxWait = maxWait;
			foreach (VoiceArray voiceArray in voiceArrays)
			{
				voiceArray.group = this;
			}
		}
	}
	public class VoiceInfo
	{
		public float approxDuration;

		public NetworkSoundEventDef sound;

		public VoiceInfo(string soundString, float approxDuration)
		{
			this.approxDuration = approxDuration;
			sound = ContentPacks.CreateAndAddNetworkSoundEventDef(soundString);
		}
	}
}