Decompiled source of AtlyssFartMod v1.0.5

FartMod.dll

Decompiled 2 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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FartMod.Core.GasCommandManagers;
using HarmonyLib;
using Mirror;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Events;
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;
		}

		public static List<string> GetAllLinesAtFile(string filePath)
		{
			Log("\tchecking single file " + Path.GetFileName(filePath));
			return File.ReadAllLines(filePath).ToList();
		}

		public static Dictionary<string, List<string>> GetParameterDictionaryFromFile(string filePath)
		{
			Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>();
			List<string> allLinesAtFile = GetAllLinesAtFile(filePath);
			foreach (string item in allLinesAtFile)
			{
				List<string> list = item.Split(new char[1] { '=' }).ToList();
				if (list.Count >= 2)
				{
					string key = list[0].Trim();
					if (!dictionary.ContainsKey(key))
					{
						dictionary.Add(key, GetParametersFromLine(list[1]));
					}
				}
			}
			return dictionary;
		}

		public static List<string> GetParametersFromLine(string line)
		{
			string[] array = line.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = array[i].Trim();
			}
			return array.ToList();
		}
	}
	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;

		public static ConfigEntry<float> BurpVolume;

		public static ConfigEntry<float> BurpParticleSize;

		public static ConfigEntry<string> BurpParticleStartColors;

		public static ConfigEntry<string> BurpParticleEndColors;

		public static ConfigEntry<float> GlobalBurpVolume;

		public static ConfigEntry<bool> BurpChaos;

		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.");
			BurpVolume = FartModCore.GetConfig().Bind<float>("Burp Effects", "BurpVolume", 0.08f, "The volume of your character's burps");
			BurpParticleSize = FartModCore.GetConfig().Bind<float>("Burp Effects", "BurpParticleSize", 0.075f, "The size of the burp particle effect.");
			BurpParticleStartColors = FartModCore.GetConfig().Bind<string>("Burp Effects", "BurpParticleStartColors", text, "Start color of burp particles.");
			BurpParticleEndColors = FartModCore.GetConfig().Bind<string>("Burp Effects", "BurpParticleEndColors", text2, "End color of burp particles.");
			BurpChaos = FartModCore.GetConfig().Bind<bool>("Global", "BurpChaos", false, "Make ALL multiplayer characters burp when they chat.");
			GlobalBurpVolume = FartModCore.GetConfig().Bind<float>("Global", "GlobalBurpVolume", 1f, "Volume of ALL multiplayer character burp.");
		}

		public static List<Color> GetStartColors(ConfigEntry<string> config)
		{
			return GetConfigColors(config);
		}

		public static List<Color> GetEndColors(ConfigEntry<string> config)
		{
			return GetConfigColors(config);
		}

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

		public static List<Color> GetColors(string config)
		{
			config = config.Replace(" ", "");
			List<string> colorHexa = config.Split(new char[1] { ',' }).ToList();
			return GetColorsFromHexaList(colorHexa);
		}

		public static List<Color> GetColorsFromHexaList(List<string> colorHexa)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			List<Color> list = new List<Color>();
			foreach (string item in colorHexa)
			{
				list.Add(FromHex(item));
			}
			return list;
		}

		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 static class NPCIdentification
	{
		public static Dictionary<string, List<string>> NPCIDS = new Dictionary<string, List<string>>();

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

		public static void InitializeDictionary()
		{
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "NPC/NPC IDs.txt");
			if (File.Exists(text))
			{
				NPCIDS = AssetUtils.GetParameterDictionaryFromFile(text);
			}
			else
			{
				Log("File " + text + " does not exist!");
			}
		}

		public static string StripNetID(string str)
		{
			string text = Regex.Replace(str, " ?\\[.*?\\]", string.Empty);
			return text.Trim();
		}

		public static GameObject GetNPC(string key)
		{
			key = key.Trim();
			if (NPCIDS.ContainsKey(key))
			{
				foreach (string item in NPCIDS[key])
				{
					GameObject val = GameObject.Find(item);
					if (Object.op_Implicit((Object)(object)val))
					{
						return val;
					}
				}
			}
			return GameObject.Find(key);
		}
	}
	public class BurpController : GasController
	{
		public static List<BurpController> allBurpControllers = new List<BurpController>();

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

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

		public override GasEffectsManager GetFartEffectsManager()
		{
			if (!Object.op_Implicit((Object)(object)fartEffectsManager))
			{
				fartEffectsManager = GasController.AddAndGetComponent<BurpEffectsManager>(((Component)this).gameObject);
				fartEffectsManager.model = GetModel();
				fartEffectsManager.Initialize(bundle);
			}
			return fartEffectsManager;
		}

		protected override void PlayAnimation()
		{
			List<AnimationSequence> list = new List<AnimationSequence>();
			AnimationClip animationClipByKeyword = GetAnimationClipByKeyword("_boobSurprise");
			if (Object.op_Implicit((Object)(object)animationClipByKeyword))
			{
				list.Add(new AnimationSequence(animationClipByKeyword, infinite: false));
			}
			AnimationClip animationClipByKeyword2 = GetAnimationClipByKeyword("_boobCheckCC");
			if (!Object.op_Implicit((Object)(object)animationClipByKeyword2))
			{
				animationClipByKeyword2 = GetAnimationClipByKeyword("_boobIdle");
			}
			if (Object.op_Implicit((Object)(object)animationClipByKeyword2))
			{
				list.Add(new AnimationSequence(animationClipByKeyword2, infinite: true));
			}
			PlayAnimation(list);
		}

		public override void FartLoop()
		{
			FartOneshot();
		}
	}
	public class BurpEffectsManager : GasEffectsManager
	{
		protected override GasEffectsConfiguration GetGasEffectsConfiguration()
		{
			if (Object.op_Implicit((Object)(object)model))
			{
				return model.GetBurpEffectsConfiguration(this);
			}
			return new BurpEffectsConfiguration(this);
		}

		protected override List<AudioClip> GetAudioClips()
		{
			return FartModCore.instance.burpCommands.GetAudioClips();
		}

		protected override Vector3 EffectDirection(GasCharacterModel model)
		{
			//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)
			return model.GetHeadTransform().forward;
		}

		protected override Vector3 EffectPosition(GasCharacterModel model)
		{
			//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)
			return model.GetHeadTransform().position;
		}

		protected override void SetEyeConditions(bool effectEnabled)
		{
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				if (effectEnabled)
				{
					gasCharacterModel.SetMouthCondition((MouthCondition)1, 1f);
				}
				else
				{
					gasCharacterModel.SetMouthCondition((MouthCondition)0, 1f);
				}
			}
		}
	}
	public class BurpEffectsConfiguration : GasEffectsConfiguration
	{
		public BurpEffectsConfiguration(BurpEffectsManager owner)
			: base(owner)
		{
		}

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

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

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

		public override float GetParticleSize()
		{
			if (IsPlayer())
			{
				return Configuration.BurpParticleSize.Value;
			}
			return particleSize;
		}
	}
	public class FartController : GasController
	{
		public static List<FartController> allFartControllers = new List<FartController>();

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

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

		public override GasEffectsManager GetFartEffectsManager()
		{
			if (!Object.op_Implicit((Object)(object)fartEffectsManager))
			{
				fartEffectsManager = GasController.AddAndGetComponent<FartEffectsManager>(((Component)this).gameObject);
				fartEffectsManager.model = GetModel();
				fartEffectsManager.Initialize(bundle);
			}
			return fartEffectsManager;
		}

		protected override void PlayAnimation()
		{
			List<AnimationSequence> list = new List<AnimationSequence>();
			AnimationClip animationClipByKeyword = GetAnimationClipByKeyword("_bottomSurprise");
			if (Object.op_Implicit((Object)(object)animationClipByKeyword))
			{
				list.Add(new AnimationSequence(animationClipByKeyword, infinite: false));
			}
			AnimationClip animationClipByKeyword2 = GetAnimationClipByKeyword("_bottomCheckCC");
			if (!Object.op_Implicit((Object)(object)animationClipByKeyword2))
			{
				animationClipByKeyword2 = GetAnimationClipByKeyword("_bottomIdle");
			}
			if (Object.op_Implicit((Object)(object)animationClipByKeyword2))
			{
				list.Add(new AnimationSequence(animationClipByKeyword2, infinite: true));
			}
			PlayAnimation(list);
		}
	}
	public class FartEffectsManager : GasEffectsManager
	{
		protected override List<AudioClip> GetAudioClips()
		{
			return FartModCore.instance.fartCommands.GetAudioClips();
		}

		protected override GasEffectsConfiguration GetGasEffectsConfiguration()
		{
			if (Object.op_Implicit((Object)(object)model))
			{
				return model.GetFartEffectsConfiguration(this);
			}
			return new FartEffectsConfiguration(this);
		}

		protected override Vector3 EffectDirection(GasCharacterModel model)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return base.EffectDirection(model);
		}

		protected override Vector3 EffectPosition(GasCharacterModel model)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return base.EffectPosition(model);
		}

		protected override void SetEffectEnabled(bool b)
		{
			base.SetEffectEnabled(b);
			if (b)
			{
				((MonoBehaviour)this).StartCoroutine(JiggleRoutine());
			}
			SetJiggleForce(0f);
		}

		private void SetJiggleForce(float forceMultiplier)
		{
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				float num = Random.Range(0.0003f, 0.0006f);
				float forcePower = num * forceMultiplier;
				gasCharacterModel.JiggleAss(forcePower);
				gasCharacterModel.JiggleTail(forcePower);
			}
		}

		private IEnumerator JiggleRoutine()
		{
			while (true)
			{
				SetJiggleForce(1f * (configuration as FartEffectsConfiguration).GetJiggleMultiplier());
				yield return (object)new WaitForEndOfFrame();
				SetJiggleForce(0f);
				yield return (object)new WaitForSeconds(0.15f);
			}
		}
	}
	public class FartEffectsConfiguration : GasEffectsConfiguration
	{
		public float jiggleMultiplier = 1f;

		public FartEffectsConfiguration(FartEffectsManager owner)
			: base(owner)
		{
		}

		protected override void SetDefaults()
		{
			base.SetDefaults();
			jiggleMultiplier = (float)((ConfigEntryBase)Configuration.JiggleIntensity).DefaultValue;
		}

		public virtual float GetJiggleMultiplier()
		{
			if (IsPlayer())
			{
				return Configuration.JiggleIntensity.Value;
			}
			return jiggleMultiplier;
		}
	}
	[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())
					{
						return;
					}
					string message = playerChat._chatMessages[playerChat._chatMessages.Count - 1];
					ChatBehaviour val = (ChatBehaviour)(object)((obj is ChatBehaviour) ? obj : null);
					if (!CheckRPCCommandReceived(val, message) && (Object)(object)val != (Object)(object)playerChat)
					{
						bool flag = false;
						if (Configuration.FartChaos.Value || flag)
						{
							instance.fartCommands.GasLoop((Component)(object)val, new List<string>());
						}
						if (Configuration.BurpChaos.Value || flag)
						{
							instance.burpCommands.GasLoop((Component)(object)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;

		public FartCommandManager fartCommands = new FartCommandManager();

		public BurpCommandManager burpCommands = new BurpCommandManager();

		public static UnityEvent onConfigRebind = new UnityEvent();

		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;
			}
			NPCFartConfig.LoadConfigEntries();
			GasCharacterModelTypes.GetCharacterModelTypes();
			NPCIdentification.InitializeDictionary();
			fartCommands.Initialize();
			burpCommands.Initialize();
			InitCommands();
			Log("Fart Mod Initialized!", forcePlay: true);
		}

		private void InitCommands()
		{
			FartCommands.AddHostCommand("rebind", "", Rebind);
			FartCommands.AddHostCommand("allAnims", "", AllAnims);
		}

		private void Rebind(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			GetConfig().Reload();
			NPCFartConfig.LoadConfigEntries();
			GasCharacterModelTypes.GetCharacterModelTypes();
			NPCIdentification.InitializeDictionary();
			onConfigRebind.Invoke();
			Log("Config file rebound!");
		}

		private void AllAnims(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			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);
				}
			}
		}

		public 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;
		}
	}
	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 class GasCharacterModel : MonoBehaviour
	{
		public GameObject owningObject;

		public virtual void Initialize(Component owningObject)
		{
			this.owningObject = owningObject.gameObject;
		}

		public virtual FartEffectsConfiguration GetFartEffectsConfiguration(FartEffectsManager controller)
		{
			return new FartEffectsConfiguration(controller);
		}

		public virtual BurpEffectsConfiguration GetBurpEffectsConfiguration(BurpEffectsManager controller)
		{
			return new BurpEffectsConfiguration(controller);
		}

		public virtual bool CompareOwner(Component owningObject)
		{
			if (Object.op_Implicit((Object)(object)this.owningObject) && Object.op_Implicit((Object)(object)owningObject))
			{
				return (Object)(object)this.owningObject.gameObject == (Object)(object)owningObject.gameObject;
			}
			return false;
		}

		public virtual void OnDelete()
		{
		}

		public virtual Animator GetAnimator()
		{
			return null;
		}

		public virtual Animator GetRaceAnimator()
		{
			return null;
		}

		public virtual Transform GetTransform()
		{
			return owningObject.transform;
		}

		public virtual Transform GetHeadTransform()
		{
			return owningObject.transform;
		}

		public virtual Vector3 AssDirection()
		{
			//IL_000c: 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_0016: 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)
			return -owningObject.transform.forward;
		}

		public virtual Vector3 AssPosition()
		{
			//IL_000c: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			return owningObject.transform.position;
		}

		public virtual void SetEyeCondition(EyeCondition eyeCondition, float time)
		{
		}

		public virtual void SetMouthCondition(MouthCondition mouthCondition, float time)
		{
		}

		public virtual void JiggleAss(float forcePower)
		{
		}

		public virtual void JiggleTail(float forcePower)
		{
		}

		public static GasCharacterModel GetModelFromComponent(Component owningObject, GameObject ownerGameObject)
		{
			Player val = default(Player);
			owningObject.gameObject.TryGetComponent<Player>(ref val);
			GasCharacterModel gasCharacterModel;
			if (Object.op_Implicit((Object)(object)val))
			{
				gasCharacterModel = ownerGameObject.AddComponent<GasPlayerCharacterModel>();
				gasCharacterModel.Initialize((Component)(object)val);
				return gasCharacterModel;
			}
			Animator componentInChildren = owningObject.GetComponentInChildren<Animator>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				gasCharacterModel = ownerGameObject.AddComponent<SimpleAnimatorGasCharacterModel>();
				(gasCharacterModel as SimpleAnimatorGasCharacterModel).owningGameObject = owningObject.gameObject;
				gasCharacterModel.Initialize((Component)(object)componentInChildren);
				return gasCharacterModel;
			}
			gasCharacterModel = ownerGameObject.AddComponent<GasCharacterModel>();
			gasCharacterModel.Initialize(owningObject);
			return gasCharacterModel;
		}

		public static bool CanMakeModel(Component owningObject)
		{
			Player val = default(Player);
			owningObject.gameObject.TryGetComponent<Player>(ref val);
			if (Object.op_Implicit((Object)(object)val))
			{
				return true;
			}
			Animator componentInChildren = owningObject.GetComponentInChildren<Animator>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				return true;
			}
			return false;
		}
	}
	public class GasController : MonoBehaviour
	{
		[Header("Components")]
		public GasCharacterModel model;

		protected AssetBundle bundle;

		[Header("Gas Effects")]
		protected GasEffectsManager fartEffectsManager;

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

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

		protected AnimationClip GetAnimationClip(int index)
		{
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				Animator raceAnimator = gasCharacterModel.GetRaceAnimator();
				if (index < raceAnimator.runtimeAnimatorController.animationClips.Length)
				{
					return raceAnimator.runtimeAnimatorController.animationClips[index];
				}
			}
			return null;
		}

		protected AnimationClip GetAnimationClip(string animName)
		{
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				Animator raceAnimator = gasCharacterModel.GetRaceAnimator();
				AnimationClip[] animationClips = raceAnimator.runtimeAnimatorController.animationClips;
				foreach (AnimationClip val in animationClips)
				{
					if (((Object)val).name == animName)
					{
						return val;
					}
				}
			}
			return null;
		}

		protected AnimationClip GetAnimationClipByKeyword(string keyword)
		{
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				Animator raceAnimator = gasCharacterModel.GetRaceAnimator();
				AnimationClip[] animationClips = raceAnimator.runtimeAnimatorController.animationClips;
				foreach (AnimationClip val in animationClips)
				{
					if (((Object)val).name.Contains(keyword))
					{
						return val;
					}
				}
			}
			return null;
		}

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

		public virtual 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)GetModel()))
			{
				return GetModel().GetAnimator();
			}
			return null;
		}

		private IEnumerator StopLoopFartRoutine()
		{
			GetPlayerAnimator();
			List<CurrentAnimationMonitor> currentAnimationMonitors = new List<CurrentAnimationMonitor>();
			if (Object.op_Implicit((Object)(object)GetModel()))
			{
				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 = GetModel().GetAnimator();
				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)GetModel()))
				{
					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();
		}

		public virtual GasEffectsManager GetFartEffectsManager()
		{
			if (!Object.op_Implicit((Object)(object)fartEffectsManager))
			{
				fartEffectsManager = GasController.AddAndGetComponent<GasEffectsManager>(((Component)this).gameObject);
				fartEffectsManager.model = GetModel();
				fartEffectsManager.Initialize(bundle);
			}
			return fartEffectsManager;
		}

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

		protected GasCharacterModel GetModel()
		{
			return model;
		}

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

		protected virtual 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);
		}

		protected void PlayAnimation(List<AnimationSequence> clips)
		{
			if (!clips.Any())
			{
				Log("No anim clip!");
				return;
			}
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				Animator animator = gasCharacterModel.GetAnimator();
				if (Object.op_Implicit((Object)(object)animator))
				{
					PlayableAnimationPlayer animationPlayer = GetAnimationPlayer();
					if (Object.op_Implicit((Object)(object)animationPlayer))
					{
						animationPlayer.StartAnimating(animator, 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 bool CompareOwner(Component owningObject)
		{
			if (!Object.op_Implicit((Object)(object)model))
			{
				return false;
			}
			return model.CompareOwner(owningObject);
		}

		public void SetOwner(Component owningObject, AssetBundle bundle)
		{
			if (!Object.op_Implicit((Object)(object)model))
			{
				model = GasCharacterModel.GetModelFromComponent(owningObject, ((Component)this).gameObject);
			}
			else
			{
				model.Initialize(owningObject);
			}
			if (Object.op_Implicit((Object)(object)owningObject))
			{
				((Object)this).name = ((Object)this).name + " " + ((Object)owningObject).name;
				((Component)this).transform.SetParent(owningObject.transform);
				GetFartEffectsManager().SetTransform(((Component)this).transform);
			}
			Initialize(bundle);
		}
	}
	public class GasEffectsManager : MonoBehaviour
	{
		private static GameObject particleSystemPrefab;

		public GasCharacterModel model;

		private AudioSource audioSource;

		private ParticleSystem particleSystem;

		private ParticleSystem gasParticle;

		private bool effectPlaying;

		private AssetBundle bundle;

		private float counter;

		protected GasEffectsConfiguration configuration = new GasEffectsConfiguration();

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			FartModCore.onConfigRebind.AddListener(new UnityAction(RebindConfig));
		}

		private void RebindConfig()
		{
			configuration = GetGasEffectsConfiguration();
		}

		private void OnDestroy()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			FartModCore.onConfigRebind.RemoveListener(new UnityAction(RebindConfig));
		}

		protected virtual GasEffectsConfiguration GetGasEffectsConfiguration()
		{
			return new GasEffectsConfiguration(this);
		}

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

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

		protected virtual List<AudioClip> GetAudioClips()
		{
			return new List<AudioClip>();
		}

		protected List<AudioClip> CollectAudioFilesFromPath(string audioPathName)
		{
			List<AudioClip> result = new List<AudioClip>();
			Log("Checking Sounds");
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), audioPathName);
			if (Directory.Exists(text))
			{
				result = CollectAudioFiles(text);
			}
			else
			{
				Log("Directory " + text + " does not exist! Creating.");
				Directory.CreateDirectory(text);
			}
			return result;
		}

		private List<AudioClip> CollectAudioFiles(string path)
		{
			List<AudioClip> list = new List<AudioClip>();
			Log("checking folder " + Path.GetFileName(path));
			string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
			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))
				{
					list.Add(val);
				}
			}
			return list;
		}

		private AudioSource GetAudioSource()
		{
			if (!Object.op_Implicit((Object)(object)audioSource))
			{
				audioSource = GasController.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()
		{
			if (!GetAudioClips().Any())
			{
				Log("No clips found of either farts or burps!");
				return;
			}
			counter = 0f;
			int index = Random.Range(0, GetAudioClips().Count);
			AudioClip clip = GetAudioClips()[index];
			GetAudioSource().clip = clip;
			GetAudioSource().Play();
			AudioSource val = GetAudioSource();
			val.spatialBlend = 1f;
			((Behaviour)this).enabled = true;
		}

		protected virtual Vector3 EffectDirection(GasCharacterModel model)
		{
			//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 model.AssDirection();
		}

		protected virtual Vector3 EffectPosition(GasCharacterModel model)
		{
			//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 model.AssPosition();
		}

		protected GasCharacterModel GetModel()
		{
			return model;
		}

		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;
		}

		protected virtual 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());
			}
			else
			{
				GetAudioSource().Stop();
				SetEyeConditions(effectEnabled: false);
			}
			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)
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				t.forward = EffectDirection(gasCharacterModel);
				t.position = EffectPosition(gasCharacterModel) + 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;
			}
			GasCharacterModel gasCharacterModel = GetModel();
			if (!Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				((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 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);
			}
		}

		protected virtual void SetEyeConditions(bool effectEnabled)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			GasCharacterModel gasCharacterModel = GetModel();
			if (Object.op_Implicit((Object)(object)gasCharacterModel))
			{
				if (effectEnabled)
				{
					gasCharacterModel.SetEyeCondition((EyeCondition)8, 1f);
					gasCharacterModel.SetMouthCondition((MouthCondition)0, 1f);
					return;
				}
				List<EyeCondition> list = new List<EyeCondition>();
				list.Add((EyeCondition)1);
				list.Add((EyeCondition)8);
				EyeCondition eyeCondition = list[Random.Range(0, list.Count)];
				gasCharacterModel.SetEyeCondition(eyeCondition, 1f);
				gasCharacterModel.SetMouthCondition((MouthCondition)1, 1f);
			}
		}

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

		private void OnDisable()
		{
			SetEffectEnabled(b: false);
		}
	}
	public class GasEffectsConfiguration
	{
		public GasEffectsManager owner;

		public float volume = 1f;

		public string startColors;

		public string endColors;

		public float particleSize;

		public GasEffectsConfiguration()
		{
			SetDefaults();
		}

		public GasEffectsConfiguration(GasEffectsManager owner)
		{
			this.owner = owner;
			SetDefaults();
		}

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

		protected bool IsPlayer()
		{
			if (Object.op_Implicit((Object)(object)owner) && owner.model is GasPlayerCharacterModel)
			{
				return (Object)(object)(owner.model as GasPlayerCharacterModel).player == (Object)(object)Player._mainPlayer;
			}
			return false;
		}

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

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

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

		public virtual float GetParticleSize()
		{
			if (IsPlayer())
			{
				return Configuration.FartParticleSize.Value;
			}
			return particleSize;
		}
	}
	public static class GasCharacterModelTypes
	{
		public static List<GasCharacterModelType> characterModelTypes = new List<GasCharacterModelType>();

		public static UnityEvent onModelTypesUpdated = new UnityEvent();

		public static void GetCharacterModelTypes()
		{
			characterModelTypes.Clear();
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "NPC/Models");
			if (Directory.Exists(text))
			{
				Log("checking folder " + Path.GetFileName(text));
				string[] files = Directory.GetFiles(text);
				string[] array = files;
				foreach (string info in array)
				{
					BoneStructureGasCharacterModelType boneStructureGasCharacterModelType = new BoneStructureGasCharacterModelType();
					boneStructureGasCharacterModelType.SetInfo(info);
					characterModelTypes.Add(boneStructureGasCharacterModelType);
				}
			}
			else
			{
				Log("Directory " + text + " does not exist! Creating.");
				Directory.CreateDirectory(text);
			}
			onModelTypesUpdated.Invoke();
		}

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

		public static GasCharacterModelType GetModelType(SimpleAnimatorGasCharacterModel model)
		{
			return characterModelTypes.Find((GasCharacterModelType x) => x.IsMatch(model));
		}
	}
	public class BoneStructureGasCharacterModelType : GasCharacterModelType
	{
		public List<string> boneStructure = new List<string>();

		public void SetInfo(string file)
		{
			name = Path.GetFileName(file);
			Dictionary<string, List<string>> parameterDictionaryFromFile = AssetUtils.GetParameterDictionaryFromFile(file);
			string key = "Bones";
			if (parameterDictionaryFromFile.ContainsKey(key))
			{
				boneStructure = parameterDictionaryFromFile[key];
			}
			string key2 = "HeadBone";
			if (parameterDictionaryFromFile.ContainsKey(key2) && parameterDictionaryFromFile[key2].Any())
			{
				headBone = parameterDictionaryFromFile[key2][0];
			}
			string key3 = "AssBones";
			if (parameterDictionaryFromFile.ContainsKey(key3))
			{
				assBones = parameterDictionaryFromFile[key3];
			}
		}

		public override bool IsMatch(SimpleAnimatorGasCharacterModel model)
		{
			if (model.skinnedMeshRenderers.Any())
			{
				SkinnedMeshRenderer val = model.skinnedMeshRenderers[0];
				for (int i = 0; i < boneStructure.Count; i++)
				{
					if (i < val.bones.Length)
					{
						if (boneStructure[i] != ((Object)val.bones[i]).name)
						{
							return false;
						}
						continue;
					}
					return false;
				}
				return true;
			}
			return false;
		}

		public override Transform GetHeadBone(SimpleAnimatorGasCharacterModel model)
		{
			if (model.skinnedMeshRenderers.Any())
			{
				return Array.Find(model.skinnedMeshRenderers[0].bones, (Transform x) => ((Object)x).name == headBone);
			}
			return base.GetHeadBone(model);
		}

		public override List<Transform> GetAssBones(SimpleAnimatorGasCharacterModel model)
		{
			if (model.skinnedMeshRenderers.Any())
			{
				return Array.FindAll(model.skinnedMeshRenderers[0].bones, (Transform x) => assBones.Contains(((Object)x).name)).ToList();
			}
			return new List<Transform>();
		}
	}
	public class GasCharacterModelType
	{
		public string name;

		public string headBone;

		public List<string> assBones = new List<string>();

		public virtual bool IsMatch(SimpleAnimatorGasCharacterModel model)
		{
			return false;
		}

		public virtual Transform GetHeadBone(SimpleAnimatorGasCharacterModel model)
		{
			return model.GetTransform();
		}

		public virtual List<Transform> GetAssBones(SimpleAnimatorGasCharacterModel model)
		{
			return new List<Transform>();
		}
	}
	public class GasPlayerCharacterModel : GasCharacterModel
	{
		public Player player;

		public override void Initialize(Component owningObject)
		{
			base.Initialize(owningObject);
			player = (Player)(object)((owningObject is Player) ? owningObject : null);
		}

		public override void SetEyeCondition(EyeCondition eyeCondition, float time)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			player._pVisual._playerRaceModel.Set_EyeCondition(eyeCondition, time);
		}

		public override void SetMouthCondition(MouthCondition mouthCondition, float time)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			player._pVisual._playerRaceModel.Set_MouthCondition(mouthCondition, time);
		}

		public override Transform GetTransform()
		{
			return ((Component)player).transform;
		}

		public override Animator GetAnimator()
		{
			return player._pVisual._visualAnimator;
		}

		public override Animator GetRaceAnimator()
		{
			return player._pVisual._playerRaceModel._raceAnimator;
		}

		public override Transform GetHeadTransform()
		{
			return player._pVisual._playerRaceModel._headBoneTransform;
		}

		public override void JiggleAss(float forcePower)
		{
			JiggleAssDynamicBones(player._pVisual._playerRaceModel._assDynamicBones.ToList(), this, forcePower);
		}

		public static void JiggleAssDynamicBones(List<DynamicBone> assBones, GasCharacterModel model, float forcePower)
		{
			//IL_0021: 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_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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < assBones.Count; i++)
			{
				DynamicBone val = assBones[i];
				float num = (((i + 1) % 2 == 0) ? 1 : (-1));
				Vector3 force = model.GetTransform().right * num * forcePower;
				val.m_Force = force;
			}
		}

		public override void JiggleTail(float forcePower)
		{
			JiggleTailDynamicBones(this, forcePower);
		}

		public static void JiggleTailDynamicBones(GasCharacterModel model, float forcePower)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			List<DynamicBone> list = new List<DynamicBone>(((Component)model.GetTransform()).GetComponentsInChildren<DynamicBone>());
			DynamicBone val = list.Find((DynamicBone x) => ((Object)x).name.Contains("tail"));
			if (Object.op_Implicit((Object)(object)val))
			{
				Vector3 force = model.GetTransform().up * forcePower;
				val.m_Force = force;
			}
		}

		private bool BonesValid()
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)player._pVisual))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)player._pVisual._playerRaceModel))
			{
				return false;
			}
			if (player._pVisual._playerRaceModel._assDynamicBones == null)
			{
				return false;
			}
			return true;
		}

		public override Vector3 AssDirection()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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)
			if (!BonesValid())
			{
				return -GetTransform().forward;
			}
			return AssDirectionFromDynamicBones(player._pVisual._playerRaceModel._assDynamicBones.ToList(), this);
		}

		public static Vector3 AssDirectionFromDynamicBones(List<DynamicBone> assBones, GasCharacterModel model)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (assBones.Count < 2)
			{
				return -model.GetTransform().forward;
			}
			Vector3 val = Vector3.zero;
			for (int i = 0; i < assBones.Count; i++)
			{
				DynamicBone val2 = assBones[i];
				val += val2.m_Root.up;
			}
			return val / (float)assBones.Count;
		}

		public static Vector3 AssDirectionFromNormalBones(List<Transform> assBones, GasCharacterModel model)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			if (assBones.Count < 2)
			{
				if (assBones.Count == 1)
				{
					return -assBones[0].forward;
				}
				return -model.GetTransform().forward;
			}
			Vector3 val = Vector3.zero;
			for (int i = 0; i < assBones.Count; i++)
			{
				Transform val2 = assBones[i];
				val += val2.up;
			}
			return val / (float)assBones.Count;
		}

		public override Vector3 AssPosition()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!BonesValid())
			{
				return GetTransform().position;
			}
			return AssPositionFromDynamicBones(player._pVisual._playerRaceModel._assDynamicBones.ToList(), this);
		}

		public static Vector3 AssPositionFromDynamicBones(List<DynamicBone> assBones, GasCharacterModel model)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (assBones.Count < 2)
			{
				return model.GetTransform().position;
			}
			Vector3 val = Vector3.zero;
			for (int i = 0; i < assBones.Count; i++)
			{
				DynamicBone val2 = assBones[i];
				val += ((Component)val2).transform.position;
			}
			return val / (float)assBones.Count;
		}

		public static Vector3 AssPositionFromNormalBones(List<Transform> assBones, GasCharacterModel model)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			if (assBones.Count < 2)
			{
				if (assBones.Count == 1)
				{
					return assBones[0].position;
				}
				return model.GetTransform().position;
			}
			Vector3 val = Vector3.zero;
			for (int i = 0; i < assBones.Count; i++)
			{
				Transform val2 = assBones[i];
				val += ((Component)val2).transform.position;
			}
			return val / (float)assBones.Count;
		}
	}
	public class SimpleAnimatorGasCharacterModel : GasCharacterModel
	{
		public GameObject owningGameObject;

		public Animator animator;

		public List<SkinnedMeshRenderer> skinnedMeshRenderers = new List<SkinnedMeshRenderer>();

		public GasCharacterModelType modelType;

		public Transform headTransform;

		public List<Transform> assBones = new List<Transform>();

		public List<DynamicBone> dynamicAssBones = new List<DynamicBone>();

		public override void Initialize(Component owningObject)
		{
			base.Initialize(owningObject);
			animator = (Animator)(object)((owningObject is Animator) ? owningObject : null);
			skinnedMeshRenderers = ((Component)animator).GetComponentsInChildren<SkinnedMeshRenderer>().ToList();
			OnModelsUpdated();
		}

		public override bool CompareOwner(Component owningObject)
		{
			if (Object.op_Implicit((Object)(object)owningGameObject) && Object.op_Implicit((Object)(object)owningObject))
			{
				return (Object)(object)owningGameObject == (Object)(object)owningObject.gameObject;
			}
			return base.CompareOwner(owningObject);
		}

		private void Awake()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			GasCharacterModelTypes.onModelTypesUpdated.AddListener(new UnityAction(OnModelsUpdated));
		}

		private void OnModelsUpdated()
		{
			modelType = GasCharacterModelTypes.GetModelType(this);
			if (modelType != null)
			{
				headTransform = modelType.GetHeadBone(this);
				assBones = modelType.GetAssBones(this);
				dynamicAssBones = assBones.Select((Transform x) => ((Component)x).GetComponent<DynamicBone>()).ToList();
				dynamicAssBones = dynamicAssBones.Where((DynamicBone x) => Object.op_Implicit((Object)(object)x)).ToList();
			}
		}

		public override FartEffectsConfiguration GetFartEffectsConfiguration(FartEffectsManager controller)
		{
			FartEffectsConfiguration fartConfiguration = NPCFartConfig.GetFartConfiguration(this, controller);
			if (fartConfiguration != null)
			{
				return fartConfiguration;
			}
			return base.GetFartEffectsConfiguration(controller);
		}

		public override BurpEffectsConfiguration GetBurpEffectsConfiguration(BurpEffectsManager controller)
		{
			BurpEffectsConfiguration burpConfiguration = NPCFartConfig.GetBurpConfiguration(this, controller);
			if (burpConfiguration != null)
			{
				return burpConfiguration;
			}
			return base.GetBurpEffectsConfiguration(controller);
		}

		private void OnDestroy()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			GasCharacterModelTypes.onModelTypesUpdated.RemoveListener(new UnityAction(OnModelsUpdated));
		}

		public override Vector3 AssDirection()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (dynamicAssBones.Any())
			{
				return GasPlayerCharacterModel.AssDirectionFromDynamicBones(dynamicAssBones, this);
			}
			return GasPlayerCharacterModel.AssDirectionFromNormalBones(assBones, this);
		}

		public override Vector3 AssPosition()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (dynamicAssBones.Any())
			{
				return GasPlayerCharacterModel.AssPositionFromDynamicBones(dynamicAssBones, this);
			}
			return GasPlayerCharacterModel.AssPositionFromNormalBones(assBones, this);
		}

		public override Animator GetAnimator()
		{
			return animator;
		}

		public override Transform GetHeadTransform()
		{
			return headTransform;
		}

		public override Animator GetRaceAnimator()
		{
			return animator;
		}

		public override void JiggleAss(float forcePower)
		{
			GasPlayerCharacterModel.JiggleAssDynamicBones(dynamicAssBones, this, forcePower);
		}

		public override void JiggleTail(float forcePower)
		{
			GasPlayerCharacterModel.JiggleTailDynamicBones(this, forcePower);
		}

		public override void SetEyeCondition(EyeCondition eyeCondition, float time)
		{
		}

		public override void SetMouthCondition(MouthCondition mouthCondition, float time)
		{
		}
	}
	public static class NPCFartConfig
	{
		public static List<NPCConfigEntry> configEntries = new List<NPCConfigEntry>();

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

		public static void LoadConfigEntries()
		{
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "NPC/Config");
			if (Directory.Exists(text))
			{
				Log("checking folder " + Path.GetFileName(text));
				string[] files = Directory.GetFiles(text);
				string[] array = files;
				foreach (string file in array)
				{
					NPCConfigEntry nPCConfigEntry = configEntries.Find((NPCConfigEntry x) => x.name == Path.GetFileName(file));
					if (nPCConfigEntry == null)
					{
						nPCConfigEntry = new NPCConfigEntry();
						configEntries.Add(nPCConfigEntry);
					}
					nPCConfigEntry.LoadInfo(file);
				}
			}
			else
			{
				Log("Directory " + text + " does not exist! Creating.");
				Directory.CreateDirectory(text);
			}
		}

		public static NPCFartEffectsConfiguration GetFartConfiguration(SimpleAnimatorGasCharacterModel model, FartEffectsManager controller)
		{
			return configEntries.Find((NPCConfigEntry x) => x.IsMatch(model))?.GetFartConfiguration(controller);
		}

		public static NPCBurpEffectsConfiguration GetBurpConfiguration(SimpleAnimatorGasCharacterModel model, BurpEffectsManager controller)
		{
			return configEntries.Find((NPCConfigEntry x) => x.IsMatch(model))?.GetBurpConfiguration(controller);
		}
	}
	public class NPCConfigEntry
	{
		public string name;

		public List<string> NPCNames = new List<string>();

		public SubGasConfig burpConfig = new SubGasConfig();

		public SubGasConfig fartConfig = new SubGasConfig();

		public bool IsMatch(SimpleAnimatorGasCharacterModel model)
		{
			if (Object.op_Implicit((Object)(object)model.owningGameObject))
			{
				string item = ((Object)model.owningGameObject).name;
				if (NPCNames.Contains(item))
				{
					return true;
				}
				string item2 = NPCIdentification.StripNetID(((Object)model.owningGameObject).name);
				if (NPCNames.Contains(item2))
				{
					return true;
				}
				foreach (string nPCName in NPCNames)
				{
					if (NPCIdentification.NPCIDS.ContainsKey(nPCName))
					{
						if (NPCIdentification.NPCIDS[nPCName].Contains(item))
						{
							return true;
						}
						if (NPCIdentification.NPCIDS[nPCName].Contains(item2))
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		public void LoadInfo(string file)
		{
			name = Path.GetFileName(file);
			Dictionary<string, List<string>> parameterDictionaryFromFile = AssetUtils.GetParameterDictionaryFromFile(file);
			NPCNames = GetStringListFromDictionary(parameterDictionaryFromFile, "Names");
			burpConfig.volume = GetFloatFromDictionary(parameterDictionaryFromFile, "BurpVolume", (float)((ConfigEntryBase)Configuration.BurpVolume).DefaultValue);
			burpConfig.particleSize = GetFloatFromDictionary(parameterDictionaryFromFile, "BurpParticleSize", (float)((ConfigEntryBase)Configuration.BurpParticleSize).DefaultValue);
			burpConfig.startColors = GetColorsFromDictionary(parameterDictionaryFromFile, "BurpParticleStartColors", (string)((ConfigEntryBase)Configuration.BurpParticleStartColors).DefaultValue);
			burpConfig.endColors = GetColorsFromDictionary(parameterDictionaryFromFile, "BurpParticleEndColors", (string)((ConfigEntryBase)Configuration.BurpParticleEndColors).DefaultValue);
			fartConfig.volume = GetFloatFromDictionary(parameterDictionaryFromFile, "FartVolume", (float)((ConfigEntryBase)Configuration.FartVolume).DefaultValue);
			fartConfig.particleSize = GetFloatFromDictionary(parameterDictionaryFromFile, "FartParticleSize", (float)((ConfigEntryBase)Configuration.FartParticleSize).DefaultValue);
			fartConfig.jiggleIntensity = GetFloatFromDictionary(parameterDictionaryFromFile, "JiggleIntensity", (float)((ConfigEntryBase)Configuration.JiggleIntensity).DefaultValue);
			fartConfig.startColors = GetColorsFromDictionary(parameterDictionaryFromFile, "FartParticleStartColors", (string)((ConfigEntryBase)Configuration.FartParticleStartColors).DefaultValue);
			fartConfig.endColors = GetColorsFromDictionary(parameterDictionaryFromFile, "FartParticleEndColors", (string)((ConfigEntryBase)Configuration.FartParticleEndColors).DefaultValue);
		}

		private float GetFloatFromDictionary(Dictionary<string, List<string>> data, string key, float defaultVal)
		{
			float result = defaultVal;
			if (data.ContainsKey(key) && data[key].Any())
			{
				float.TryParse(data[key][0], out result);
			}
			return result;
		}

		private List<Color> GetColorsFromDictionary(Dictionary<string, List<string>> data, string key, string defaultColorHexa)
		{
			if (data.ContainsKey(key))
			{
				List<string> colorHexa = data[key];
				return Configuration.GetColorsFromHexaList(colorHexa);
			}
			return Configuration.GetColors(defaultColorHexa);
		}

		private List<string> GetStringListFromDictionary(Dictionary<string, List<string>> data, string key)
		{
			if (data.ContainsKey(key))
			{
				return data[key];
			}
			return new List<string>();
		}

		public NPCFartEffectsConfiguration GetFartConfiguration(FartEffectsManager controller)
		{
			NPCFartEffectsConfiguration nPCFartEffectsConfiguration = new NPCFartEffectsConfiguration(controller);
			nPCFartEffectsConfiguration.entry = this;
			return nPCFartEffectsConfiguration;
		}

		public NPCBurpEffectsConfiguration GetBurpConfiguration(BurpEffectsManager controller)
		{
			NPCBurpEffectsConfiguration nPCBurpEffectsConfiguration = new NPCBurpEffectsConfiguration(controller);
			nPCBurpEffectsConfiguration.entry = this;
			return nPCBurpEffectsConfiguration;
		}
	}
	public class SubGasConfig
	{
		public float volume;

		public List<Color> startColors = new List<Color>();

		public List<Color> endColors = new List<Color>();

		public float particleSize;

		public float jiggleIntensity;
	}
	public class NPCFartEffectsConfiguration : FartEffectsConfiguration
	{
		public NPCConfigEntry entry;

		public NPCFartEffectsConfiguration(FartEffectsManager owner)
			: base(owner)
		{
		}

		public override float GetVolume()
		{
			float num = volume;
			if (entry != null)
			{
				num = entry.fartConfig.volume;
			}
			return num + (Configuration.GlobalFartVolume.Value - 1f);
		}

		public override List<Color> GetStartColors()
		{
			if (entry != null)
			{
				return entry.fartConfig.startColors;
			}
			return Configuration.GetColors(startColors);
		}

		public override List<Color> GetEndColors()
		{
			if (entry != null)
			{
				return entry.fartConfig.endColors;
			}
			return Configuration.GetColors(endColors);
		}

		public override float GetParticleSize()
		{
			if (entry != null)
			{
				return entry.fartConfig.particleSize;
			}
			return particleSize;
		}

		public override float GetJiggleMultiplier()
		{
			if (entry != null)
			{
				return entry.fartConfig.jiggleIntensity;
			}
			return jiggleMultiplier;
		}
	}
	public class NPCBurpEffectsConfiguration : BurpEffectsConfiguration
	{
		public NPCConfigEntry entry;

		public NPCBurpEffectsConfiguration(BurpEffectsManager owner)
			: base(owner)
		{
		}

		public override float GetVolume()
		{
			float num = volume;
			if (entry != null)
			{
				num = entry.burpConfig.volume;
			}
			return num + (Configuration.GlobalBurpVolume.Value - 1f);
		}

		public override List<Color> GetStartColors()
		{
			if (entry != null)
			{
				return entry.burpConfig.startColors;
			}
			return Configuration.GetColors(startColors);
		}

		public override List<Color> GetEndColors()
		{
			if (entry != null)
			{
				return entry.burpConfig.endColors;
			}
			return Configuration.GetColors(endColors);
		}

		public override float GetParticleSize()
		{
			if (entry != null)
			{
				return entry.burpConfig.particleSize;
			}
			return particleSize;
		}
	}
}
namespace FartMod.Core.GasCommandManagers
{
	public class BurpCommandManager : GasCommandManager<BurpController>
	{
		public override List<AudioClip> GetAudioClips()
		{
			if (!sounds.Any())
			{
				sounds = CollectAudioFilesFromPath("Burp Audio");
			}
			return sounds;
		}

		protected override string GetGasVerb()
		{
			return "burp";
		}

		protected override GasController GetCharacterGasController(Component owningObject)
		{
			if (Object.op_Implicit((Object)(object)owningObject))
			{
				GasController gasController = BurpController.allBurpControllers.Find((BurpController x) => x.CompareOwner(owningObject));
				if (!Object.op_Implicit((Object)(object)gasController))
				{
					if (!GasCharacterModel.CanMakeModel(owningObject))
					{
						return null;
					}
					gasController = Object.Instantiate<GasController>(GetOriginalGasController());
					((Component)gasController).gameObject.SetActive(true);
					gasController.SetOwner(owningObject, FartModCore.instance.GetAssetBundle());
				}
				return gasController;
			}
			return null;
		}

		protected override ConfigEntry<bool> GetChaosConfig()
		{
			return Configuration.BurpChaos;
		}

		protected override ConfigEntry<float> GetVolumeConfig()
		{
			return Configuration.BurpVolume;
		}

		protected override ConfigEntry<float> GetGlobalVolumeConfig()
		{
			return Configuration.GlobalBurpVolume;
		}

		protected override ConfigEntry<float> GetParticleSizeConfig()
		{
			return Configuration.BurpParticleSize;
		}
	}
	public class FartCommandManager : GasCommandManager<FartController>
	{
		public override List<AudioClip> GetAudioClips()
		{
			if (!sounds.Any())
			{
				sounds = CollectAudioFilesFromPath("Audio");
			}
			return sounds;
		}

		public override void Initialize()
		{
			FartModCore.FartCommands.AddHostCommand(GetGasVerb() + "jiggle", "", SetFartJiggle);
			base.Initialize();
		}

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

		public List<AudioClip> sounds = new List<AudioClip>();

		public virtual List<AudioClip> GetAudioClips()
		{
			return new List<AudioClip>();
		}

		protected List<AudioClip> CollectAudioFilesFromPath(string audioPathName)
		{
			List<AudioClip> result = new List<AudioClip>();
			FartModCore.Log("Checking Sounds");
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), audioPathName);
			if (Directory.Exists(text))
			{
				result = CollectAudioFiles(text);
			}
			else
			{
				FartModCore.Log("Directory " + text + " does not exist! Creating.");
				Directory.CreateDirectory(text);
			}
			return result;
		}

		private List<AudioClip> CollectAudioFiles(string path)
		{
			List<AudioClip> list = new List<AudioClip>();
			FartModCore.Log("checking folder " + Path.GetFileName(path));
			string[] files = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories);
			string[] array = files;
			foreach (string path2 in array)
			{
				FartModCore.Log("\tchecking single file " + Path.GetFileName(path2));
				AudioClip val = AssetUtils.LoadAudioFromWebRequest(path2, (AudioType)0);
				if (Object.op_Implicit((Object)(object)val))
				{
					list.Add(val);
				}
			}
			return list;
		}

		protected virtual string GetGasVerb()
		{
			return "fart";
		}

		public virtual void Initialize()
		{
			string gasVerb = GetGasVerb();
			FartModCore.FartCommands.AddCommand(gasVerb, "", GasLoop);
			FartModCore.FartCommands.AddCommand(gasVerb + "oneshot", "", GasOneshot);
			FartModCore.FartCommands.AddCommand(gasVerb + "infinite", "", GasLoopInfinite);
			FartModCore.FartCommands.AddCommand("stop" + gasVerb + "ing", "", StopGas);
			FartModCore.FartCommands.AddHostCommand(gasVerb + "chaos", "", ToggleGasChaos);
			FartModCore.FartCommands.AddHostCommand(gasVerb + "volume", "", SetGasVolume);
			FartModCore.FartCommands.AddHostCommand("global" + gasVerb + "volume", "", SetGlobalGasVolume);
			FartModCore.FartCommands.AddHostCommand(gasVerb + "size", "", SetGasParticleSize);
			string text = "interact";
			FartModCore.FartCommands.AddHostCommand(text + gasVerb, "", InteractGasLoopInfinite);
			FartModCore.FartCommands.AddHostCommand(text + "stop" + gasVerb + "ing", "", InteractStopGas);
			string text2 = "target";
			FartModCore.FartCommands.AddHostCommand(text2 + gasVerb, "", TargetGasLoopInfinite);
			FartModCore.FartCommands.AddHostCommand(text2 + "stop" + gasVerb + "ing", "", TargetStopGas);
			GetOriginalGasController();
			GetAudioClips();
			FartModCore.Log(GetGasVerbUpper() + " Commands loaded");
		}

		protected virtual GasController GetCharacterGasController(Component owningObject)
		{
			if (Object.op_Implicit((Object)(object)owningObject))
			{
				GasController gasController = FartController.allFartControllers.Find((FartController x) => x.CompareOwner(owningObject));
				if (!Object.op_Implicit((Object)(object)gasController))
				{
					if (!GasCharacterModel.CanMakeModel(owningObject))
					{
						return null;
					}
					gasController = Object.Instantiate<GasController>(GetOriginalGasController());
					((Component)gasController).gameObject.SetActive(true);
					gasController.SetOwner(owningObject, FartModCore.instance.GetAssetBundle());
				}
				return gasController;
			}
			return null;
		}

		protected virtual ConfigEntry<bool> GetChaosConfig()
		{
			return Configuration.FartChaos;
		}

		protected virtual ConfigEntry<float> GetVolumeConfig()
		{
			return Configuration.FartVolume;
		}

		protected virtual ConfigEntry<float> GetGlobalVolumeConfig()
		{
			return Configuration.GlobalFartVolume;
		}

		protected virtual ConfigEntry<float> GetParticleSizeConfig()
		{
			return Configuration.FartParticleSize;
		}

		private void ToggleGasChaos(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			GetChaosConfig().Value = !GetChaosConfig().Value;
			string text = (GetChaosConfig().Value ? "on" : "off");
			FartModCore.Log(GetGasVerbUpper() + " chaos " + text + "!");
		}

		private void SetGasVolume(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			GetVolumeConfig().Value = GetFloat(parameters, 0, GetVolumeConfig().Value, out var success);
			if (success)
			{
				FartModCore.Log("Set " + GetGasVerb() + " volume to " + GetVolumeConfig().Value + "!");
			}
		}

		private void SetGlobalGasVolume(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			GetGlobalVolumeConfig().Value = GetFloat(parameters, 0, GetGlobalVolumeConfig().Value, out var success);
			if (success)
			{
				FartModCore.Log("Set global " + GetGasVerb() + " volume to " + GetGlobalVolumeConfig().Value + "!");
			}
		}

		private void SetGasParticleSize(ChatBehaviour chatBehaviour, List<string> parameters)
		{
			GetParticleSizeConfig().Value = GetFloat(parameters, 0, GetParticleSizeConfig().Value, out var success);
			if (success)
			{
				FartModCore.Log("Set " + GetGasVerb() + " particle size to " + GetParticleSizeConfig().Value + "!");
			}
		}

		private string GetGasVerbUpper()
		{
			string text = GetGasVerb();
			if (text.Length == 1)
			{
				char.ToUpper(text[0]);
			}
			else
			{
				text = char.ToUpper(text[0]) + text.Substring(1);
			}
			return text;
		}

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

		public void GasLoop(Component owningObject, List<string> parameters)
		{
			GasController characterGasController = GetCharacterGasController(owningObject);
			if (Object.op_Implicit((Object)(object)characterGasController))
			{
				characterGasController.FartLoop();
			}
		}

		private void GasOneshot(Component owningObject, List<string> parameters)
		{
			GasController characterGasController = GetCharacterGasController(owningObject);
			if (Object.op_Implicit((Object)(object)characterGasController))
			{
				characterGasController.FartOneshot();
			}
		}

		private void GasLoopInfinite(Component owningObject, List<string> parameters)
		{
			GasController characterGasController = GetCharacterGasController(owningObject);
			if (Object.op_Implicit((Object)(object)characterGasController))
			{
				characterGasController.FartLoopInfinite();
			}
		}

		private void StopGas(Component owningObject, List<string> parameters)
		{
			GasController characterGasController = GetCharacterGasController(owningObject);
			if (Object.op_Implicit((Object)(object)characterGasController))
			{
				characterGasController.StopFarting();
			}
		}

		private void NPCGasLoopInfinite(Component owningObject, List<string> parameters)
		{
			if (parameters.Any())
			{
				string key = parameters[0];
				GameObject nPC = NPCIdentification.GetNPC(key);
				if (Object.op_Implicit((Object)(object)nPC))
				{
					GasLoopInfinite((Component)(object)nPC.transform, parameters);
				}
			}
		}

		private void NPCStopGas(Component owningObject, List<string> parameters)
		{
			if (parameters.Any())
			{
				string key = parameters[0];
				GameObject nPC = NPCIdentification.GetNPC(key);
				if (Object.op_Implicit((Object)(object)nPC))
				{
					StopGas((Component)(object)nPC.transform, parameters);
				}
			}
		}

		private IEnumerator DelayAction(UnityAction action)
		{
			yield return (object)new WaitForSeconds(0.25f);
			action.Invoke();
		}

		public GameObject GetTarget(Component owningObject)
		{
			Player component = owningObject.GetComponent<Player>();
			if (Object.op_Implicit((Object)(object)component))
			{
				if (Object.op_Implicit((Object)(object)component._pTargeting._foundEntity))
				{
					Creep component2 = ((Component)component._pTargeting._foundEntity).GetComponent<Creep>();
					if (Object.op_Implicit((Object)(object)component2))
					{
						FartModCore.Log(((object)component2).ToString());
						return component2._creepObject;
					}
				}
				else
				{
					FartModCore.Log("No entity found");
				}
			}
			return null;
		}

		private void TargetGasLoopInfinite(Component owningObject, List<string> parameters)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			UnityAction action = (UnityAction)delegate
			{
				if (Object.op_Implicit((Object)(object)owningObject))
				{
					GameObject target = GetTarget(owningObject);
					if (Object.op_Implicit((Object)(object)target))
					{
						GasLoopInfinite((Component)(object)target.transform, parameters);
					}
				}
			};
			((MonoBehaviour)FartModCore.instance).StartCoroutine(DelayAction(action));
		}

		private void TargetStopGas(Component owningObject, List<string> parameters)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			UnityAction action = (UnityAction)delegate
			{
				if (Object.op_Implicit((Object)(object)owningObject))
				{
					GameObject target = GetTarget(owningObject);
					if (Object.op_Implicit((Object)(object)target))
					{
						StopGas((Component)(object)target.transform, parameters);
					}
				}
			};
			((MonoBehaviour)FartModCore.instance).StartCoroutine(DelayAction(action));
		}

		public Transform GetInteractTarget(Component owningObject)
		{
			PlayerInteract component = owningObject.GetComponent<PlayerInteract>();
			if (Object.op_Implicit((Object)(object)component))
			{
				FieldInfo field = typeof(PlayerInteract).GetField("_interactableObj", BindingFlags.Instance | BindingFlags.NonPublic);
				object? value = field.GetValue(component);
				Transform val = (Transform)((value is Transform) ? value : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					NetNPC componentInParent = ((Component)val).GetComponentInParent<NetNPC>();
					if (Object.op_Implicit((Object)(object)componentInParent))
					{
						return ((Component)componentInParent).transform;
					}
					Animator componentInParent2 = ((Component)val).GetComponentInParent<Animator>();
					if (Object.op_Implicit((Object)(object)componentInParent2))
					{
						return ((Component)componentInParent2).transform;
					}
					return val;
				}
			}
			return null;
		}

		private void InteractGasLoopInfinite(Component owningObject, List<string> parameters)
		{
			if (Object.op_Implicit((Object)(object)owningObject))
			{
				Transform interactTarget = GetInteractTarget(owningObject);
				if (Object.op_Implicit((Object)(object)interactTarget))
				{
					GasLoopInfinite((Component)(object)((Component)interactTarget).transform, parameters);
				}
			}
		}

		private void InteractStopGas(Component owningObject, List<string> parameters)
		{
			if (Object.op_Implicit((Object)(object)owningObject))
			{
				Transform interactTarget = GetInteractTarget(owningObject);
				if (Object.op_Implicit((Object)(object)interactTarget))
				{
					StopGas((Component)(object)((Component)interactTarget).transform, parameters);
				}
			}
		}

		protected GasController GetOriginalGasController()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)originalFartController))
			{
				GameObject val = new GameObject(GetGasVerbUpper() + "Controller");
				val.transform.SetParent(((Component)FartModCore.instance).transform);
				originalFartController = val.AddComponent<T>();
				originalFartController.Initialize(FartModCore.instance.GetAssetBundle());
				((Component)originalFartController).gameObject.SetActive(false);
			}
			return originalFartController;
		}
	}
}