Decompiled source of AtlyssFartMod v1.0.1

FartMod.dll

Decompiled 7 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Mirror;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Networking;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FartMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FartMod")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9955ca6d-c427-470f-80ed-9c0c104267e2")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FartMod;

public static class AssetUtils
{
	private static void Log(string message)
	{
		FartModCore.Log(message);
	}

	private static bool IsInvalidPath(string path)
	{
		return path.EndsWith(".txt") || !path.Contains(".");
	}

	public static T GetWebRequest<T>(Func<UnityWebRequest> webRequest) where T : DownloadHandler
	{
		try
		{
			UnityWebRequest val = webRequest();
			val.SendWebRequest();
			while (!val.isDone)
			{
			}
			if (val != null)
			{
				DownloadHandler downloadHandler = val.downloadHandler;
				if (downloadHandler != null && downloadHandler is T)
				{
					return (T)(object)downloadHandler;
				}
			}
			else
			{
				Log("www is null " + val.url);
			}
		}
		catch
		{
		}
		return default(T);
	}

	public static string GetWebRequestPath(string path)
	{
		Log("path: " + path);
		path = "file:///" + path.Replace("\\", "/");
		return path;
	}

	public static AssetBundle LoadAssetBundleFromWebRequest(string path)
	{
		if (IsInvalidPath(path))
		{
			return null;
		}
		path = GetWebRequestPath(path);
		DownloadHandlerAssetBundle webRequest = AssetUtils.GetWebRequest<DownloadHandlerAssetBundle>((Func<UnityWebRequest>)(() => UnityWebRequestAssetBundle.GetAssetBundle(path)));
		if (webRequest != null)
		{
			return webRequest.assetBundle;
		}
		return null;
	}

	public static AssetBundle LoadAssetBundle(string bundlePath)
	{
		string text = Path.Combine(Paths.PluginPath, bundlePath);
		if (!File.Exists(text))
		{
			return null;
		}
		return AssetBundle.LoadFromFile(text);
	}

	public static AudioClip LoadAudioFromWebRequest(string path, AudioType audioType)
	{
		//IL_000e: 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)
		if (IsInvalidPath(path))
		{
			return null;
		}
		path = GetWebRequestPath(path);
		DownloadHandlerAudioClip webRequest = AssetUtils.GetWebRequest<DownloadHandlerAudioClip>((Func<UnityWebRequest>)(() => UnityWebRequestMultimedia.GetAudioClip(path, audioType)));
		if (webRequest != null)
		{
			return webRequest.audioClip;
		}
		return null;
	}

	public static List<AudioClip> PreloadAudioClips(string folderName)
	{
		List<AudioClip> list = new List<AudioClip>();
		Log("Checking Sounds");
		string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), folderName);
		if (Directory.Exists(text))
		{
			list.Clear();
			CollectAudioFiles(text);
		}
		else
		{
			Log("Directory " + text + " does not exist! Creating.");
			Directory.CreateDirectory(text);
		}
		return list;
	}

	private static List<AudioClip> CollectAudioFiles(string path)
	{
		List<AudioClip> list = new List<AudioClip>();
		Log("checking folder " + Path.GetFileName(path));
		string[] files = Directory.GetFiles(path);
		string[] array = files;
		foreach (string path2 in array)
		{
			Log("\tchecking single file " + Path.GetFileName(path2));
			AudioClip val = LoadAudioFromWebRequest(path2, (AudioType)0);
			if (Object.op_Implicit((Object)(object)val))
			{
				list.Add(val);
			}
		}
		return list;
	}
}
internal static class Configuration
{
	public static ConfigEntry<float> FartVolume;

	public static ConfigEntry<float> FartParticleSize;

	public static ConfigEntry<float> JiggleIntensity;

	public static ConfigEntry<string> FartParticleStartColors;

	public static ConfigEntry<string> FartParticleEndColors;

	public static ConfigEntry<float> GlobalFartVolume;

	public static ConfigEntry<bool> FartChaos;

	internal static void BindConfiguration()
	{
		FartVolume = FartModCore.GetConfig().Bind<float>("Fart Effects", "FartVolume", 0.08f, "The volume of your character's farts");
		FartParticleSize = FartModCore.GetConfig().Bind<float>("Fart Effects", "FartParticleSize", 0.075f, "The size of the fart particle effect.");
		JiggleIntensity = FartModCore.GetConfig().Bind<float>("Fart Effects", "JiggleIntensity", 1f, "Multiplier for how intense your butt jiggles from farts.");
		string text = "CFFF4E, 77F131, 349300";
		FartParticleStartColors = FartModCore.GetConfig().Bind<string>("Fart Effects", "FartParticleStartColors", text, "Start color of fart particles.");
		string text2 = "CFFF4E, DCFF40, 92B204";
		FartParticleEndColors = FartModCore.GetConfig().Bind<string>("Fart Effects", "FartParticleEndColors", text2, "End color of fart particles.");
		FartChaos = FartModCore.GetConfig().Bind<bool>("Global", "FartChaos", false, "Make ALL multiplayer characters fart when they chat.");
		GlobalFartVolume = FartModCore.GetConfig().Bind<float>("Global", "GlobalFartVolume", 1f, "Volume of ALL multiplayer character farts.");
	}

	public static List<Color> GetStartColors()
	{
		return GetConfigColors(FartParticleStartColors);
	}

	public static List<Color> GetEndColors()
	{
		return GetConfigColors(FartParticleEndColors);
	}

	private static List<Color> GetConfigColors(ConfigEntry<string> config)
	{
		return GetColors(config.Value);
	}

	public static List<Color> GetColors(string config)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		config = config.Replace(" ", "");
		List<string> list = config.Split(new char[1] { ',' }).ToList();
		List<Color> list2 = new List<Color>();
		foreach (string item in list)
		{
			list2.Add(FromHex(item));
		}
		return list2;
	}

	public static Color FromHex(string hex)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		if (hex.Length < 6)
		{
			Debug.LogError((object)"Needs a string with a length of at least 6");
			return Color.green;
		}
		string s = hex.Substring(0, 2);
		string s2 = hex.Substring(2, 2);
		string s3 = hex.Substring(4, 2);
		string s4 = ((hex.Length < 8) ? "FF" : hex.Substring(6, 2));
		return new Color((float)int.Parse(s, NumberStyles.HexNumber) / 255f, (float)int.Parse(s2, NumberStyles.HexNumber) / 255f, (float)int.Parse(s3, NumberStyles.HexNumber) / 255f, (float)int.Parse(s4, NumberStyles.HexNumber) / 255f);
	}
}
public class FartController : MonoBehaviour
{
	public class CurrentAnimationMonitor
	{
		public Animator animator;

		public int layer;

		public AnimationClip currentClip;

		public List<AnimationClip> clipsToIgnore = new List<AnimationClip>();

		public CurrentAnimationMonitor(Animator animator, int layer)
		{
			this.animator = animator;
			this.layer = layer;
			currentClip = GetCurrentClip();
		}

		public AnimationClip GetCurrentClip()
		{
			AnimatorClipInfo[] currentAnimatorClipInfo = animator.GetCurrentAnimatorClipInfo(layer);
			if (currentAnimatorClipInfo.Any())
			{
				return ((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip;
			}
			return null;
		}

		public string Debug()
		{
			string text = animator.GetLayerName(layer);
			AnimationClip val = GetCurrentClip();
			if (Object.op_Implicit((Object)(object)val))
			{
				text = text + " " + ((Object)val).name;
			}
			return text;
		}

		public bool IsDifferent()
		{
			AnimationClip val = GetCurrentClip();
			if (clipsToIgnore.Contains(val))
			{
				return false;
			}
			return (Object)(object)currentClip != (Object)(object)val;
		}
	}

	public static List<FartController> allFartControllers = new List<FartController>();

	[Header("Components")]
	public Player owner;

	private AssetBundle bundle;

	[Header("Fart Effects")]
	private FartEffectsManager fartEffectsManager;

	[Header("Animation Player")]
	private PlayableAnimationPlayer animPlayer;

	private void Awake()
	{
		if (!allFartControllers.Contains(this))
		{
			allFartControllers.Add(this);
		}
	}

	private void OnDestroy()
	{
		allFartControllers.Remove(this);
	}

	private void Log(string message, bool force = false)
	{
		FartModCore.Log(message, force);
	}

	private AnimationClip GetAnimationClip(int index)
	{
		Player player = GetPlayer();
		if (Object.op_Implicit((Object)(object)player))
		{
			Animator raceAnimator = player._pVisual._playerRaceModel._raceAnimator;
			if (index < raceAnimator.runtimeAnimatorController.animationClips.Length)
			{
				return raceAnimator.runtimeAnimatorController.animationClips[index];
			}
		}
		return null;
	}

	public void FartOneshot()
	{
		((MonoBehaviour)this).StopAllCoroutines();
		Fart();
	}

	public void FartLoop()
	{
		PlayAnimation();
		((MonoBehaviour)this).StartCoroutine(LoopFartRoutine());
		((MonoBehaviour)this).StartCoroutine(StopLoopFartRoutine());
	}

	private IEnumerator LoopFartRoutine()
	{
		while (GetAnimationPlayer().currentClip == 0)
		{
			yield return null;
		}
		((MonoBehaviour)this).StartCoroutine(FartLoopInfiniteRoutine());
	}

	private void StopFartLoop()
	{
		((MonoBehaviour)this).StopAllCoroutines();
		((Behaviour)GetAnimationPlayer()).enabled = false;
	}

	private Animator GetPlayerAnimator()
	{
		if (Object.op_Implicit((Object)(object)GetPlayer()))
		{
			return GetPlayer()._pVisual._visualAnimator;
		}
		return null;
	}

	private IEnumerator StopLoopFartRoutine()
	{
		GetPlayerAnimator();
		List<CurrentAnimationMonitor> currentAnimationMonitors = new List<CurrentAnimationMonitor>();
		if (Object.op_Implicit((Object)(object)GetPlayer()))
		{
			List<int> clipIndexes = new List<int> { 1 };
			List<AnimationClip> clipsToIgnore = new List<AnimationClip>();
			foreach (int j in clipIndexes)
			{
				AnimationClip clip = GetAnimationClip(j);
				if (Object.op_Implicit((Object)(object)clip))
				{
					clipsToIgnore.Add(clip);
				}
			}
			Animator playerAnim = GetPlayer()._pVisual._visualAnimator;
			for (int i = 0; i < playerAnim.layerCount; i++)
			{
				if (i != 2 && i != 6 && i != 4)
				{
					currentAnimationMonitors.Add(new CurrentAnimationMonitor(playerAnim, i)
					{
						clipsToIgnore = clipsToIgnore
					});
				}
			}
		}
		while (true)
		{
			if (!Object.op_Implicit((Object)(object)GetPlayer()))
			{
				StopFartLoop();
				yield break;
			}
			if (!currentAnimationMonitors.Any())
			{
				Log("No monitors");
				StopFartLoop();
				yield break;
			}
			CurrentAnimationMonitor monitor = currentAnimationMonitors.Find((CurrentAnimationMonitor x) => x.IsDifferent());
			if (monitor != null)
			{
				break;
			}
			yield return null;
		}
		StopFartLoop();
	}

	public void FartLoopInfinite()
	{
		((MonoBehaviour)this).StopAllCoroutines();
		((MonoBehaviour)this).StartCoroutine(FartLoopInfiniteRoutine());
	}

	public void StopFarting()
	{
		((MonoBehaviour)this).StopAllCoroutines();
	}

	private void Fart()
	{
		GetFartEffectsManager().StartEffect();
	}

	private FartEffectsManager GetFartEffectsManager()
	{
		if (!Object.op_Implicit((Object)(object)fartEffectsManager))
		{
			fartEffectsManager = FartController.AddAndGetComponent<FartEffectsManager>(((Component)this).gameObject);
			fartEffectsManager.owner = GetPlayer();
			fartEffectsManager.Initialize(bundle);
		}
		return fartEffectsManager;
	}

	private PlayableAnimationPlayer GetAnimationPlayer()
	{
		if (!Object.op_Implicit((Object)(object)animPlayer))
		{
			animPlayer = FartController.AddAndGetComponent<PlayableAnimationPlayer>(((Component)this).gameObject);
			((Behaviour)animPlayer).enabled = false;
		}
		return animPlayer;
	}

	private Player GetPlayer()
	{
		return owner;
	}

	private IEnumerator FartLoopInfiniteRoutine()
	{
		yield return (object)new WaitForSeconds(0.5f);
		while (Object.op_Implicit((Object)(object)GetPlayer()))
		{
			Fart();
			float delayTime = Random.Range(2f, 5f);
			yield return (object)new WaitForSeconds(delayTime);
		}
		((MonoBehaviour)this).StopAllCoroutines();
	}

	private void PlayAnimation()
	{
		List<AnimationSequence> list = new List<AnimationSequence>();
		AnimationClip animationClip = GetAnimationClip(77);
		if (Object.op_Implicit((Object)(object)animationClip))
		{
			list.Add(new AnimationSequence(animationClip, infinite: false));
		}
		AnimationClip animationClip2 = GetAnimationClip(76);
		if (Object.op_Implicit((Object)(object)animationClip2))
		{
			list.Add(new AnimationSequence(animationClip2, infinite: true));
		}
		PlayAnimation(list);
	}

	private void PlayAnimation(AnimationClip clip)
	{
		List<AnimationSequence> list = new List<AnimationSequence>();
		list.Add(new AnimationSequence(clip, infinite: false));
		PlayAnimation(list);
	}

	private void PlayAnimation(List<AnimationSequence> clips)
	{
		if (!clips.Any())
		{
			Log("No anim clip!");
			return;
		}
		Player player = GetPlayer();
		if (Object.op_Implicit((Object)(object)player))
		{
			Animator visualAnimator = player._pVisual._visualAnimator;
			if (Object.op_Implicit((Object)(object)visualAnimator))
			{
				PlayableAnimationPlayer animationPlayer = GetAnimationPlayer();
				if (Object.op_Implicit((Object)(object)animationPlayer))
				{
					animationPlayer.StartAnimating(visualAnimator, clips);
					return;
				}
				Log("No anim player!");
			}
			Log("No animator on character!");
		}
		Log("No character!");
	}

	public void Initialize(AssetBundle bundle)
	{
		this.bundle = bundle;
		GetFartEffectsManager();
		GetAnimationPlayer();
	}

	public static T AddAndGetComponent<T>(GameObject gameObject) where T : Component
	{
		T val = gameObject.GetComponent<T>();
		if (!Object.op_Implicit((Object)(object)val))
		{
			val = gameObject.AddComponent<T>();
		}
		return val;
	}

	public void SetOwner(Player owner, AssetBundle bundle)
	{
		this.owner = owner;
		if (Object.op_Implicit((Object)(object)owner))
		{
			((Object)this).name = ((Object)this).name + " " + ((Object)owner).name;
			((Component)this).transform.SetParent(((Component)owner).transform);
			GetFartEffectsManager().SetTransform(((Component)this).transform);
		}
		Initialize(bundle);
	}
}
public class FartEffectsManager : MonoBehaviour
{
	private static List<AudioClip> sounds = new List<AudioClip>();

	private static GameObject particleSystemPrefab;

	public Player owner;

	private AudioSource audioSource;

	private ParticleSystem particleSystem;

	private ParticleSystem gasParticle;

	private bool effectPlaying;

	private AssetBundle bundle;

	private float counter;

	private FartEffectsConfiguration configuration = new FartEffectsConfiguration();

	public void Initialize(AssetBundle bundle)
	{
		this.bundle = bundle;
		configuration = new FartEffectsConfiguration(this);
		PreloadAudioClips();
		GetParticleSystemPrefab();
		GetAudioSource();
		GetParticleSystem();
		((Behaviour)this).enabled = false;
	}

	private GameObject GetParticleSystemPrefab()
	{
		if (!Object.op_Implicit((Object)(object)particleSystemPrefab))
		{
			particleSystemPrefab = bundle.LoadAsset<GameObject>("FartParticle");
		}
		return particleSystemPrefab;
	}

	private void PreloadAudioClips()
	{
		if (!sounds.Any())
		{
			Log("Checking Sounds");
			string path = "Audio";
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), path);
			if (Directory.Exists(text))
			{
				sounds.Clear();
				CollectAudioFiles(text);
			}
			else
			{
				Log("Directory " + text + " does not exist! Creating.");
				Directory.CreateDirectory(text);
			}
		}
	}

	private void CollectAudioFiles(string path)
	{
		Log("checking folder " + Path.GetFileName(path));
		string[] files = Directory.GetFiles(path);
		string[] array = files;
		foreach (string path2 in array)
		{
			Log("\tchecking single file " + Path.GetFileName(path2));
			AudioClip val = AssetUtils.LoadAudioFromWebRequest(path2, (AudioType)0);
			if (Object.op_Implicit((Object)(object)val))
			{
				sounds.Add(val);
			}
		}
	}

	private AudioSource GetAudioSource()
	{
		if (!Object.op_Implicit((Object)(object)audioSource))
		{
			audioSource = FartController.AddAndGetComponent<AudioSource>(((Component)this).gameObject);
		}
		if (Object.op_Implicit((Object)(object)audioSource))
		{
			audioSource.volume = configuration.GetVolume();
		}
		return audioSource;
	}

	private ParticleSystem GetParticleSystem()
	{
		if (!Object.op_Implicit((Object)(object)particleSystem))
		{
			particleSystem = ((Component)this).GetComponentInChildren<ParticleSystem>();
			if (!Object.op_Implicit((Object)(object)particleSystem) && Object.op_Implicit((Object)(object)GetParticleSystemPrefab()))
			{
				particleSystem = Object.Instantiate<GameObject>(GetParticleSystemPrefab(), ((Component)this).transform).GetComponent<ParticleSystem>();
			}
		}
		return particleSystem;
	}

	public void StartEffect()
	{
		counter = 0f;
		int index = Random.Range(0, sounds.Count);
		AudioClip clip = sounds[index];
		GetAudioSource().clip = clip;
		GetAudioSource().Play();
		Player player = GetPlayer();
		AudioSource val = GetAudioSource();
		AudioSource componentInChildren = ((Component)player).GetComponentInChildren<AudioSource>();
		if (Object.op_Implicit((Object)(object)componentInChildren))
		{
			val.spatialBlend = componentInChildren.spatialBlend;
		}
		((Behaviour)this).enabled = true;
	}

	private Vector3 AssDirection(Player player)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Vector3.zero;
		DynamicBone[] assDynamicBones = player._pVisual._playerRaceModel._assDynamicBones;
		foreach (DynamicBone val2 in assDynamicBones)
		{
			val += val2.m_Root.up;
		}
		return val / (float)assDynamicBones.Length;
	}

	private Vector3 AssPosition(Player player)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: 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)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = Vector3.zero;
		DynamicBone[] assDynamicBones = player._pVisual._playerRaceModel._assDynamicBones;
		foreach (DynamicBone val2 in assDynamicBones)
		{
			val += ((Component)val2).transform.position;
		}
		return val / (float)assDynamicBones.Length;
	}

	private Player GetPlayer()
	{
		return owner;
	}

	private void Log(string message, bool force = false)
	{
		FartModCore.Log(message, force);
	}

	private Gradient GetGradientColorKeys(List<Color> colors, Gradient gradient)
	{
		//IL_0013: 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_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_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		List<GradientColorKey> list = new List<GradientColorKey>();
		GradientColorKey item = default(GradientColorKey);
		for (int i = 0; i < gradient.colorKeys.Length; i++)
		{
			GradientColorKey val = gradient.colorKeys[i];
			Color val2 = val.color;
			if (colors.Any())
			{
				val2 = ((i >= colors.Count) ? colors[0] : colors[i]);
			}
			((GradientColorKey)(ref item))..ctor(val2, val.time);
			list.Add(item);
		}
		Gradient val3 = new Gradient();
		val3.SetKeys(list.ToArray(), gradient.alphaKeys);
		return val3;
	}

	private ParticleSystem GetGasParticle()
	{
		if (!Object.op_Implicit((Object)(object)gasParticle))
		{
			gasParticle = ((Component)((Component)GetParticleSystem()).transform.Find("Gas")).GetComponent<ParticleSystem>();
		}
		return gasParticle;
	}

	private Gradient GetStartGradient()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		ColorOverLifetimeModule colorOverLifetime = GetGasParticle().colorOverLifetime;
		MinMaxGradient color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
		return ((MinMaxGradient)(ref color)).gradientMax;
	}

	private Gradient GetEndGradient()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		ColorOverLifetimeModule colorOverLifetime = GetGasParticle().colorOverLifetime;
		MinMaxGradient color = ((ColorOverLifetimeModule)(ref colorOverLifetime)).color;
		return ((MinMaxGradient)(ref color)).gradientMin;
	}

	private void SetEffectEnabled(bool b)
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		((MonoBehaviour)this).StopAllCoroutines();
		if (b)
		{
			List<Color> startColors = configuration.GetStartColors();
			Gradient gradientColorKeys = GetGradientColorKeys(startColors, GetStartGradient());
			List<Color> endColors = configuration.GetEndColors();
			Gradient gradientColorKeys2 = GetGradientColorKeys(endColors, GetEndGradient());
			ColorOverLifetimeModule colorOverLifetime = GetGasParticle().colorOverLifetime;
			((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(gradientColorKeys2, gradientColorKeys);
			((MonoBehaviour)this).StartCoroutine(EyeConditionRoutine());
			((MonoBehaviour)this).StartCoroutine(JiggleRoutine());
		}
		else
		{
			GetAudioSource().Stop();
		}
		SetJiggleForce(0f);
		SetParticleEnabled(b);
		effectPlaying = b;
	}

	public void SetTransform(Transform t)
	{
		//IL_001a: 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)
		//IL_002e: 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)
		Player player = GetPlayer();
		if (Object.op_Implicit((Object)(object)player))
		{
			t.forward = AssDirection(player);
			t.position = AssPosition(player) + t.forward * 0.75f;
		}
	}

	private void Update()
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)GetAudioSource().clip))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		if (counter >= GetAudioSource().clip.length)
		{
			((Behaviour)this).enabled = false;
			return;
		}
		Player player = GetPlayer();
		if (!Object.op_Implicit((Object)(object)player))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		audioSource.volume = configuration.GetVolume();
		((Component)GetParticleSystem()).transform.localScale = Vector3.one * configuration.GetParticleSize();
		SetTransform(((Component)this).transform);
		if (true)
		{
			if (!effectPlaying)
			{
				SetEffectEnabled(b: true);
			}
		}
		else if (effectPlaying)
		{
			SetEffectEnabled(b: false);
		}
		counter += Time.deltaTime;
	}

	private void SetJiggleForce(float forceMultiplier)
	{
		//IL_0062: 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_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		Player player = GetPlayer();
		if (Object.op_Implicit((Object)(object)player))
		{
			float num = Random.Range(0.0003f, 0.0006f);
			float num2 = num * forceMultiplier;
			DynamicBone[] assDynamicBones = player._pVisual._playerRaceModel._assDynamicBones;
			for (int i = 0; i < assDynamicBones.Length; i++)
			{
				DynamicBone val = assDynamicBones[i];
				float num3 = (((i + 1) % 2 == 0) ? 1 : (-1));
				Vector3 force = ((Component)player).transform.right * num3 * num2;
				val.m_Force = force;
			}
			List<DynamicBone> list = new List<DynamicBone>(((Component)player).gameObject.GetComponentsInChildren<DynamicBone>());
			DynamicBone val2 = list.Find((DynamicBone x) => ((Object)x).name.Contains("tail"));
			if (Object.op_Implicit((Object)(object)val2))
			{
				Vector3 force2 = ((Component)player).transform.up * num2;
				val2.m_Force = force2;
			}
		}
	}

	private IEnumerator JiggleRoutine()
	{
		while (true)
		{
			SetJiggleForce(1f * configuration.GetJiggleMultiplier());
			yield return (object)new WaitForEndOfFrame();
			SetJiggleForce(0f);
			yield return (object)new WaitForSeconds(0.15f);
		}
	}

	private void SetParticleEnabled(bool b)
	{
		ParticleSystem val = GetParticleSystem();
		if (Object.op_Implicit((Object)(object)val))
		{
			if (b)
			{
				val.Play(true);
			}
			else
			{
				val.Stop(true);
			}
		}
		else
		{
			Log("NO PARTICLE", force: true);
		}
	}

	private void SetEyeConditions()
	{
		Player player = GetPlayer();
		if (Object.op_Implicit((Object)(object)player))
		{
			player._pVisual._playerRaceModel.Set_EyeCondition((EyeCondition)8, 1f);
			player._pVisual._playerRaceModel.Set_MouthCondition((MouthCondition)0, 1f);
		}
	}

	private IEnumerator EyeConditionRoutine()
	{
		while (true)
		{
			SetEyeConditions();
			yield return (object)new WaitForEndOfFrame();
		}
	}

	private void OnDisable()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		SetEffectEnabled(b: false);
		Player player = GetPlayer();
		if (Object.op_Implicit((Object)(object)player))
		{
			List<EyeCondition> list = new List<EyeCondition>();
			list.Add((EyeCondition)1);
			list.Add((EyeCondition)8);
			EyeCondition val = list[Random.Range(0, list.Count)];
			player._pVisual._playerRaceModel.Set_EyeCondition(val, 1f);
			player._pVisual._playerRaceModel.Set_MouthCondition((MouthCondition)1, 1f);
		}
	}
}
public class FartEffectsConfiguration
{
	public FartEffectsManager owner;

	public float volume = 1f;

	public string startColors;

	public string endColors;

	public float particleSize;

	public float jiggleMultiplier = 1f;

	public FartEffectsConfiguration()
	{
		SetDefaults();
	}

	public FartEffectsConfiguration(FartEffectsManager owner)
	{
		this.owner = owner;
		SetDefaults();
	}

	private void SetDefaults()
	{
		volume = (float)((ConfigEntryBase)Configuration.FartVolume).DefaultValue;
		startColors = (string)((ConfigEntryBase)Configuration.FartParticleStartColors).DefaultValue;
		endColors = (string)((ConfigEntryBase)Configuration.FartParticleEndColors).DefaultValue;
		jiggleMultiplier = (float)((ConfigEntryBase)Configuration.JiggleIntensity).DefaultValue;
		particleSize = (float)((ConfigEntryBase)Configuration.FartParticleSize).DefaultValue;
	}

	private bool IsPlayer()
	{
		if (Object.op_Implicit((Object)(object)owner))
		{
			return (Object)(object)owner.owner == (Object)(object)Player._mainPlayer;
		}
		return false;
	}

	public float GetVolume()
	{
		float value = volume;
		if (IsPlayer())
		{
			value = Configuration.FartVolume.Value;
		}
		return value + (Configuration.GlobalFartVolume.Value - 1f);
	}

	public float GetJiggleMultiplier()
	{
		if (IsPlayer())
		{
			return Configuration.JiggleIntensity.Value;
		}
		return jiggleMultiplier;
	}

	public List<Color> GetStartColors()
	{
		if (IsPlayer())
		{
			return Configuration.GetStartColors();
		}
		return Configuration.GetColors(startColors);
	}

	public List<Color> GetEndColors()
	{
		if (IsPlayer())
		{
			return Configuration.GetEndColors();
		}
		return Configuration.GetColors(endColors);
	}

	public float GetParticleSize()
	{
		if (IsPlayer())
		{
			return Configuration.FartParticleSize.Value;
		}
		return particleSize;
	}
}
[BepInPlugin("TransientGuy.Atlyss.FartMod", "FartMod", "1.2.3.4")]
public class FartModCore : BaseUnityPlugin
{
	public class ChatCommand
	{
		public string commandKey;

		public string commandMessage;

		public Action<ChatBehaviour, List<string>> action;

		public ChatCommand(string commandKey, string commandMessage, Action<ChatBehaviour, List<string>> action)
		{
			this.commandKey = commandKey;
			this.action = action;
		}

		public void InvokeAction(ChatBehaviour chatBehaviour)
		{
			InvokeAction(chatBehaviour, new List<string>());
		}

		public void InvokeAction(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			action(chatBehaviour, parameters);
			if (!string.IsNullOrEmpty(commandMessage))
			{
				chatBehaviour.New_ChatMessage("<color=#ea8e09> " + commandMessage + "</color>");
			}
		}
	}

	public static class FartCommands
	{
		[HarmonyPatch(typeof(ChatBehaviour), "Send_ChatMessage")]
		public static class AddCommandsPatch
		{
			[HarmonyPrefix]
			public static bool Send_ChatMessage_Prefix(ChatBehaviour __instance, string _message)
			{
				if (CheckHostCommand(__instance, _message))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(ChatBehaviour), "InvokeUserCode_Rpc_RecieveChatMessage__String__Boolean__ChatChannel")]
		public static class RecieveChatMessagePatch
		{
			[HarmonyPostfix]
			public static void RecieveChatMessage_Prefix(ChatBehaviour __instance, NetworkBehaviour obj, NetworkReader reader, NetworkConnectionToClient senderConnection)
			{
				if (!Object.op_Implicit((Object)(object)obj) || !(obj is ChatBehaviour))
				{
					return;
				}
				ChatBehaviour playerChat = GetPlayerChat();
				if (Object.op_Implicit((Object)(object)playerChat) && playerChat._chatMessages.Any())
				{
					string message = playerChat._chatMessages[playerChat._chatMessages.Count - 1];
					ChatBehaviour val = (ChatBehaviour)(object)((obj is ChatBehaviour) ? obj : null);
					bool flag = CheckRPCCommandReceived(val, message);
					if (Configuration.FartChaos.Value && !flag && (Object)(object)val != (Object)(object)playerChat)
					{
						instance.FartLoop(val, new List<string>());
					}
				}
			}
		}

		public static ChatBehaviour playerChat;

		public static List<ChatCommand> allChatCommands = new List<ChatCommand>();

		public static List<ChatCommand> hostChatCommands = new List<ChatCommand>();

		public static ChatBehaviour GetPlayerChat()
		{
			if (!Object.op_Implicit((Object)(object)playerChat))
			{
				Player mainPlayer = Player._mainPlayer;
				if (Object.op_Implicit((Object)(object)mainPlayer))
				{
					playerChat = ((Component)mainPlayer).GetComponentInChildren<ChatBehaviour>();
				}
			}
			return playerChat;
		}

		public static void AddCommand(string commandKey, string commandMessage, Action<ChatBehaviour, List<string>> action)
		{
			allChatCommands.Add(new ChatCommand(commandKey, commandMessage, action));
		}

		public static void AddHostCommand(string commandKey, string commandMessage, Action<ChatBehaviour, List<string>> action)
		{
			hostChatCommands.Add(new ChatCommand(commandKey, commandMessage, action));
		}

		private static bool CheckHostCommand(ChatBehaviour __instance, string _message)
		{
			if (_message == null)
			{
				return false;
			}
			if (!_message.Any())
			{
				return false;
			}
			if (_message[0] != '/')
			{
				return false;
			}
			_message = _message.Substring(1);
			List<string> parameters = _message.Split(new char[1] { ' ' }).ToList();
			ChatCommand chatCommand = hostChatCommands.Find((ChatCommand x) => parameters[0] == x.commandKey);
			if (chatCommand != null)
			{
				parameters.RemoveAt(0);
				parameters = parameters.Where((string x) => !string.IsNullOrEmpty(x)).ToList();
				chatCommand.InvokeAction(__instance, parameters);
				return true;
			}
			return false;
		}

		private static bool CheckRPCCommandReceived(ChatBehaviour __instance, string _message)
		{
			bool flag = false;
			foreach (ChatCommand allChatCommand in allChatCommands)
			{
				if (_message.Contains(allChatCommand.commandKey))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				return false;
			}
			string[] array = _message.Split(new char[1] { '/' });
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = text.Replace("<", "");
				foreach (ChatCommand allChatCommand2 in allChatCommands)
				{
					if (text2 == allChatCommand2.commandKey)
					{
						allChatCommand2.InvokeAction(__instance);
						return true;
					}
				}
			}
			return false;
		}
	}

	internal static ManualLogSource Logger;

	public static FartModCore instance;

	private FartController originalFartController;

	private AssetBundle bundle;

	internal static ConfigFile GetConfig()
	{
		return ((BaseUnityPlugin)instance).Config;
	}

	public static void Log(string message, bool forcePlay = false)
	{
		Logger.LogInfo((object)message);
	}

	private void Awake()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Expected O, but got Unknown
		instance = this;
		Logger = ((BaseUnityPlugin)this).Logger;
		Configuration.BindConfiguration();
		Harmony val = new Harmony("FartMod");
		try
		{
			val.PatchAll();
		}
		catch (Exception ex)
		{
			Log(ex.ToString());
			throw;
		}
		GetOriginalFartController();
		InitCommands();
		Log("Fart Mod Initialized!", forcePlay: true);
	}

	private void InitCommands()
	{
		FartCommands.AddCommand("fart", "Rippin ass!", FartLoop);
		FartCommands.AddCommand("fartoneshot", "Rippin ass!", FartOneshot);
		FartCommands.AddCommand("fartinfinite", "Rippin ass!", FartLoopInfinite);
		FartCommands.AddCommand("stopfarting", "", StopFarting);
		FartCommands.AddHostCommand("rebind", "", Rebind);
		FartCommands.AddHostCommand("fartchaos", "", ToggleFartChaos);
		FartCommands.AddHostCommand("fartvolume", "", SetFartVolume);
		FartCommands.AddHostCommand("globalfartvolume", "", SetGlobalFartVolume);
		FartCommands.AddHostCommand("fartsize", "", SetFarticleSize);
		FartCommands.AddHostCommand("fartjiggle", "", SetFartJiggle);
		Log("Fart Commands loaded");
	}

	private void Rebind(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		Log("Config file rebound!");
		GetConfig().Reload();
	}

	private void ToggleFartChaos(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		Configuration.FartChaos.Value = !Configuration.FartChaos.Value;
		string text = (Configuration.FartChaos.Value ? "on" : "off");
		Log("Fart chaos " + text + "!");
	}

	private float GetFloat(List<string> parameters, int index, float defaultValue, out bool success)
	{
		if (index >= parameters.Count)
		{
			Log("Not enough parameters given for command");
			success = false;
			return defaultValue;
		}
		if (float.TryParse(parameters[index], out var result))
		{
			success = true;
			return result;
		}
		Log("Given parameter " + parameters[index] + " is of incorrect type");
		success = false;
		return defaultValue;
	}

	private void SetFartVolume(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		Configuration.FartVolume.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
		if (success)
		{
			Log("Set fart volume to " + Configuration.FartVolume.Value + "!");
		}
	}

	private void SetGlobalFartVolume(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		Configuration.GlobalFartVolume.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
		if (success)
		{
			Log("Set global fart volume to " + Configuration.GlobalFartVolume.Value + "!");
		}
	}

	private void SetFarticleSize(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		Configuration.FartParticleSize.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
		if (success)
		{
			Log("Set fart particle size to " + Configuration.FartParticleSize.Value + "!");
		}
	}

	private void SetFartJiggle(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		Configuration.JiggleIntensity.Value = GetFloat(parameters, 0, Configuration.FartVolume.Value, out var success);
		if (success)
		{
			Log("Set fart jiggle intensity to " + Configuration.JiggleIntensity.Value + "!");
		}
	}

	private void AllAnims(ChatBehaviour chatBehaviour)
	{
		Player mainPlayer = Player._mainPlayer;
		if (!Object.op_Implicit((Object)(object)mainPlayer))
		{
			return;
		}
		Animator raceAnimator = mainPlayer._pVisual._playerRaceModel._raceAnimator;
		for (int i = 0; i < raceAnimator.runtimeAnimatorController.animationClips.Length; i++)
		{
			AnimationClip val = raceAnimator.runtimeAnimatorController.animationClips[i];
			if (Object.op_Implicit((Object)(object)val))
			{
				Log(((Object)val).name + " " + i);
			}
		}
	}

	private void FartLoop(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		FartController characterFartController = GetCharacterFartController(chatBehaviour);
		if (Object.op_Implicit((Object)(object)characterFartController))
		{
			characterFartController.FartLoop();
		}
	}

	private void FartOneshot(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		FartController characterFartController = GetCharacterFartController(chatBehaviour);
		if (Object.op_Implicit((Object)(object)characterFartController))
		{
			characterFartController.FartOneshot();
		}
	}

	private void FartLoopInfinite(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		FartController characterFartController = GetCharacterFartController(chatBehaviour);
		if (Object.op_Implicit((Object)(object)characterFartController))
		{
			characterFartController.FartLoopInfinite();
		}
	}

	private void StopFarting(ChatBehaviour chatBehaviour, List<string> parameters)
	{
		FartController characterFartController = GetCharacterFartController(chatBehaviour);
		if (Object.op_Implicit((Object)(object)characterFartController))
		{
			characterFartController.StopFarting();
		}
	}

	private FartController GetCharacterFartController(ChatBehaviour chatBehaviour)
	{
		Player owningPlayer = ((Component)chatBehaviour).GetComponent<Player>();
		if (Object.op_Implicit((Object)(object)owningPlayer))
		{
			FartController fartController = FartController.allFartControllers.Find((FartController x) => (Object)(object)x.owner == (Object)(object)owningPlayer);
			if (!Object.op_Implicit((Object)(object)fartController))
			{
				fartController = Object.Instantiate<FartController>(GetOriginalFartController());
				((Component)fartController).gameObject.SetActive(true);
				fartController.SetOwner(owningPlayer, GetAssetBundle());
			}
			return fartController;
		}
		return null;
	}

	private FartController GetOriginalFartController()
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		if (!Object.op_Implicit((Object)(object)originalFartController))
		{
			GameObject val = new GameObject("FartController");
			val.transform.SetParent(((Component)this).transform);
			originalFartController = val.AddComponent<FartController>();
			originalFartController.Initialize(GetAssetBundle());
			((Component)originalFartController).gameObject.SetActive(false);
		}
		return originalFartController;
	}

	private AssetBundle GetAssetBundle()
	{
		if (!Object.op_Implicit((Object)(object)bundle))
		{
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			bundle = AssetUtils.LoadAssetBundle(Path.Combine(directoryName, "Assets/atlyss"));
		}
		return bundle;
	}
}
public class PlayableAnimationPlayer : MonoBehaviour
{
	public Animator animator;

	private PlayableGraph playableGraph;

	private AnimationClipPlayable anim;

	public int currentClip;

	private List<AnimationSequence> animationSequence = new List<AnimationSequence>();

	private AnimationSequence GetCurrentClip()
	{
		if (animationSequence.Any())
		{
			return (currentClip >= animationSequence.Count) ? animationSequence[animationSequence.Count - 1] : animationSequence[currentClip];
		}
		return null;
	}

	public void StartAnimating(Animator animator, List<AnimationSequence> animationSequence)
	{
		currentClip = 0;
		this.animator = animator;
		this.animationSequence = animationSequence;
		if (Object.op_Implicit((Object)(object)animator) && animationSequence.Any())
		{
			((Behaviour)this).enabled = true;
			PlayCurrentClip();
		}
		else
		{
			((Behaviour)this).enabled = false;
		}
	}

	private void PlayCurrentClip()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		DestroyGraph();
		anim = AnimationPlayableUtilities.PlayClip(animator, GetCurrentClip().animationClip, ref playableGraph);
	}

	private void Update()
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)animator))
		{
			((Behaviour)this).enabled = false;
			return;
		}
		try
		{
			if (!(PlayableExtensions.GetTime<AnimationClipPlayable>(anim) >= (double)((AnimationClipPlayable)(ref anim)).GetAnimationClip().length))
			{
				return;
			}
			currentClip++;
			if (currentClip < this.animationSequence.Count)
			{
				PlayCurrentClip();
				return;
			}
			AnimationSequence animationSequence = GetCurrentClip();
			if (animationSequence == null || !animationSequence.infinite)
			{
				((Behaviour)this).enabled = false;
			}
		}
		catch
		{
			FartModCore.Log("Animation playing failed");
			((Behaviour)this).enabled = false;
		}
	}

	private void DestroyGraph()
	{
		if (Object.op_Implicit((Object)(object)animator))
		{
			animator.Rebind();
			animator.Update(0f);
		}
		if (((PlayableGraph)(ref playableGraph)).IsValid())
		{
			((PlayableGraph)(ref playableGraph)).Destroy();
		}
	}

	private void OnDisable()
	{
		DestroyGraph();
	}
}
public class AnimationSequence
{
	public AnimationClip animationClip;

	public bool infinite;

	public AnimationSequence(AnimationClip animationClip, bool infinite)
	{
		this.animationClip = animationClip;
		this.infinite = infinite;
	}
}