Decompiled source of Full Belly v3.1.1

tony4twentys-Full Belly.dll

Decompiled 2 weeks 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.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Full Belly")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Full Belly")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("940386f2-efcb-440c-a8e5-aa2361ab032b")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace FullBellyMod;

[BepInPlugin("tony4twentys.full_belly", "Full Belly", "3.1.1")]
[BepInProcess("PEAK.exe")]
public class FullBellyPlugin : BaseUnityPlugin
{
	[CompilerGenerated]
	private sealed class <RetryConfigSyncCoroutine>d__43 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public FullBellyPlugin <>4__this;

		private int <attempts>5__1;

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

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

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

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

		private bool MoveNext()
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<attempts>5__1 = 0;
				break;
			case 1:
				<>1__state = -1;
				break;
			case 2:
				<>1__state = -1;
				break;
			}
			while (<attempts>5__1 < 1)
			{
				<attempts>5__1++;
				if (!PhotonNetwork.IsConnectedAndReady)
				{
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 1;
					return true;
				}
				<>4__this.AttemptConfigSync(forceSync: true);
				if (<attempts>5__1 < 1)
				{
					<>2__current = (object)new WaitForSeconds(1f);
					<>1__state = 2;
					return true;
				}
			}
			<>4__this.configSyncRetryCoroutine = null;
			return false;
		}

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

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

	public static FullBellyPlugin Instance;

	internal static ConfigEntry<float> cfgFullnessThreshold;

	private static ConfigEntry<string> cfgIgnoredItems;

	internal static ConfigEntry<bool> cfgShowPercentageDisplay;

	internal static ConfigEntry<int> cfgPercentageFontSize;

	internal static ConfigEntry<float> cfgPercentageOffsetX;

	internal static ConfigEntry<float> cfgPercentageOffsetY;

	internal static ConfigEntry<string> cfgPercentageColor;

	internal static ConfigEntry<KeyCode> cfgUIEditModeKey;

	internal static ConfigEntry<KeyCode> cfgUISpeedCycleKey;

	internal static ConfigEntry<float> cfgFullnessDecayInterval;

	internal static ConfigEntry<float> cfgFullnessDecayAmount;

	internal static ConfigEntry<float> cfgBloatedDecayInterval;

	internal static ConfigEntry<float> cfgBloatedDecayAmount;

	internal static ConfigEntry<bool> cfgEnableOvereating;

	internal static ConfigEntry<bool> cfgEnableFarting;

	internal static ConfigEntry<float> cfgFartChance;

	internal static ConfigEntry<float> cfgDecayFartChance;

	internal static float syncedFullnessThreshold;

	internal static float syncedFullnessDecayInterval;

	internal static float syncedFullnessDecayAmount;

	internal static float syncedBloatedDecayInterval;

	internal static float syncedBloatedDecayAmount;

	internal static bool syncedEnableOvereating;

	internal static bool syncedEnableFarting;

	internal static float syncedFartChance;

	internal static float syncedDecayFartChance;

	internal static bool isStaminaInfoForkedDetected;

	internal PhotonView view;

	internal Coroutine configSyncRetryCoroutine;

	private bool wasConnectedAndReady;

	private bool wasMasterClient;

	private bool wasInRoom;

	internal const string ROOM_PROP_KEY = "FullBellyConfig";

	internal const string HANDSHAKE_KEY = "FullBellyHandshake";

	internal const int HANDSHAKE_VERSION = 1;

	internal static bool isHandshakeValid;

	public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

	private void Awake()
	{
		//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d3: Expected O, but got Unknown
		cfgFullnessThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly", "FullnessThreshold", 0.4f, "Food consumption amount needed to become full (threshold = 100%). Example: 0.40 means 40% of max hunger restore = 100% full.");
		cfgIgnoredItems = ((BaseUnityPlugin)this).Config.Bind<string>("Full Belly", "IgnoredItems", "", "Comma-separated list of item names to ignore. Consume the items you want Full Belly to ignore and check the logs to find the names it uses to enter here.");
		cfgShowPercentageDisplay = ((BaseUnityPlugin)this).Config.Bind<bool>("Full Belly - UI", "ShowPercentageDisplay", true, "Display food consumption percentage. Visible whenever percentage > 0%.");
		cfgPercentageFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Full Belly - UI", "PercentageFontSize", 24, "Font size for the percentage display text.");
		cfgPercentageOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - UI", "PercentageOffsetX", 0f, "X offset from center (adjusted via Ctrl+Arrow keys in edit mode).");
		cfgPercentageOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - UI", "PercentageOffsetY", 0f, "Y offset from center for lower third positioning (adjusted via Ctrl+Arrow keys in edit mode).");
		cfgPercentageColor = ((BaseUnityPlugin)this).Config.Bind<string>("Full Belly - UI", "PercentageColor", "#FFFFFFFF", "Percentage text color (hex only, #RRGGBB or #RRGGBBAA).");
		cfgUIEditModeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Full Belly - UI", "UIEditModeKey", (KeyCode)13, "Key to press with Ctrl to toggle UI edit mode (default: Enter/Return).");
		cfgUISpeedCycleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Full Belly - UI", "UISpeedCycleKey", (KeyCode)9, "Key to press with Ctrl to cycle through move speeds (5, 10, 25, 50, 100 pixels/sec).");
		cfgFullnessDecayInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - Decay", "FullnessDecayInterval", 3f, "Seconds between fullness decay ticks.");
		cfgFullnessDecayAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - Decay", "FullnessDecayAmount", 0.01f, "Fullness percentage decayed per tick (relative to threshold, e.g., 0.01 = 1% of threshold per interval).");
		cfgBloatedDecayInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - Decay", "BloatedDecayInterval", 3f, "Seconds between bloated decay ticks.");
		cfgBloatedDecayAmount = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - Decay", "BloatedDecayAmount", 0.01f, "Bloated percentage decayed per tick (actual food value, not relative to threshold).");
		cfgEnableOvereating = ((BaseUnityPlugin)this).Config.Bind<bool>("Full Belly - Overeating", "EnableOvereating", true, "Enable overeating penalties - eating while full can cause Bloated affliction.");
		cfgEnableFarting = ((BaseUnityPlugin)this).Config.Bind<bool>("Full Belly - Farting", "EnableFarting", true, "Enable random farting when eating while full.");
		cfgFartChance = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - Farting", "FartChance", 0.01f, "Chance to fart when eating while full (0.01 = 1% chance).");
		cfgDecayFartChance = ((BaseUnityPlugin)this).Config.Bind<float>("Full Belly - Farting", "DecayFartChance", 0.05f, "Chance to fart during bloated decay tick (0.05 = 5% chance per decay interval).");
		syncedFullnessThreshold = cfgFullnessThreshold.Value;
		syncedFullnessDecayInterval = cfgFullnessDecayInterval.Value;
		syncedFullnessDecayAmount = cfgFullnessDecayAmount.Value;
		syncedBloatedDecayInterval = cfgBloatedDecayInterval.Value;
		syncedBloatedDecayAmount = cfgBloatedDecayAmount.Value;
		syncedEnableOvereating = cfgEnableOvereating.Value;
		syncedEnableFarting = cfgEnableFarting.Value;
		syncedFartChance = cfgFartChance.Value;
		syncedDecayFartChance = cfgDecayFartChance.Value;
		Instance = this;
		if (!PhotonNetwork.InRoom)
		{
			isHandshakeValid = true;
			Logger.LogInfo((object)"[Full Belly] Single player mode - handshake valid");
		}
		else if (PhotonNetwork.IsMasterClient)
		{
			isHandshakeValid = true;
			Logger.LogInfo((object)"[Full Belly] Host mode - handshake valid");
		}
		Logger.LogInfo((object)"Full Belly mod started.");
		try
		{
			BloatedAffliction.CreateBloatedAffliction(Logger, (BaseUnityPlugin)(object)this);
			((MonoBehaviour)this).StartCoroutine(BloatedAffliction.CreateBarAfflictionComponent(Logger));
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("[Full Belly] Failed to register Bloated affliction in Awake(): " + ex.Message));
			if (ex.InnerException != null)
			{
				Logger.LogError((object)("[Full Belly] Inner Exception: " + ex.InnerException.Message));
			}
		}
		FullBellyManager.Initialize(Logger, syncedFullnessThreshold, cfgIgnoredItems.Value);
		Harmony val = new Harmony("tony4twentys.full_belly");
		val.PatchAll();
		SceneManager.activeSceneChanged += OnSceneChanged;
	}

	private void OnSceneChanged(Scene oldScene, Scene newScene)
	{
		if (configSyncRetryCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(configSyncRetryCoroutine);
			configSyncRetryCoroutine = null;
		}
		configSyncRetryCoroutine = ((MonoBehaviour)this).StartCoroutine(RetryConfigSyncCoroutine());
	}

	internal void AttemptConfigSync(bool forceSync = false)
	{
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Expected O, but got Unknown
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Expected O, but got Unknown
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Expected O, but got Unknown
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Expected O, but got Unknown
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Expected O, but got Unknown
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Expected O, but got Unknown
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Expected O, but got Unknown
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b6: Expected O, but got Unknown
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Expected O, but got Unknown
		//IL_01d4: Expected O, but got Unknown
		if (!PhotonNetwork.IsConnectedAndReady)
		{
			return;
		}
		if ((Object)(object)view == (Object)null)
		{
			try
			{
				view = ((Component)this).gameObject.GetComponent<PhotonView>();
				if ((Object)(object)view == (Object)null)
				{
					view = ((Component)this).gameObject.AddComponent<PhotonView>();
				}
				if (view.ViewID == 0)
				{
					view.ViewID = 999998;
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Full Belly] Could not setup PhotonView: " + ex.Message));
				return;
			}
		}
		bool inRoom = PhotonNetwork.InRoom;
		bool isMasterClient = PhotonNetwork.IsMasterClient;
		if (isMasterClient && inRoom)
		{
			try
			{
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"FullBellyHandshake", (object)1);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_Threshold", (object)cfgFullnessThreshold.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_FullnessDecayInterval", (object)cfgFullnessDecayInterval.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_FullnessDecayAmount", (object)cfgFullnessDecayAmount.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_BloatedDecayInterval", (object)cfgBloatedDecayInterval.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_BloatedDecayAmount", (object)cfgBloatedDecayAmount.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_EnableOvereating", (object)cfgEnableOvereating.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_EnableFarting", (object)cfgEnableFarting.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_FartChance", (object)cfgFartChance.Value);
				((Dictionary<object, object>)val).Add((object)"FullBellyConfig_DecayFartChance", (object)cfgDecayFartChance.Value);
				Hashtable val2 = val;
				PhotonNetwork.CurrentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
				isHandshakeValid = true;
				Logger.LogInfo((object)"[Full Belly] Host updated room properties with config and handshake");
				if ((Object)(object)view != (Object)null)
				{
					view.RPC("SyncHostSettings", (RpcTarget)1, new object[9] { cfgFullnessThreshold.Value, cfgFullnessDecayInterval.Value, cfgFullnessDecayAmount.Value, cfgBloatedDecayInterval.Value, cfgBloatedDecayAmount.Value, cfgEnableOvereating.Value, cfgEnableFarting.Value, cfgFartChance.Value, cfgDecayFartChance.Value });
					Logger.LogInfo((object)"[Full Belly] Host sent config sync RPC to clients");
				}
				return;
			}
			catch (Exception ex2)
			{
				Logger.LogWarning((object)("[Full Belly] Failed to sync config as host: " + ex2.Message));
				return;
			}
		}
		if (!(!isMasterClient && inRoom))
		{
			return;
		}
		try
		{
			Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties;
			if (((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"FullBellyHandshake"))
			{
				int num = (int)customProperties[(object)"FullBellyHandshake"];
				isHandshakeValid = num == 1;
				if (isHandshakeValid)
				{
					Logger.LogInfo((object)$"[Full Belly] Handshake valid - host has mod (version {num})");
					if (((Dictionary<object, object>)(object)customProperties).ContainsKey((object)"FullBellyConfig_Threshold"))
					{
						ApplyConfigFromRoomProperties(customProperties);
						Logger.LogInfo((object)"[Full Belly] Client loaded config from room properties");
					}
					else if (forceSync && (Object)(object)view != (Object)null)
					{
						Logger.LogInfo((object)"[Full Belly] Client requesting config from host (room properties not available)");
						((MonoBehaviour)this).StartCoroutine(RetryConfigSyncCoroutine());
					}
				}
				else
				{
					Logger.LogWarning((object)$"[Full Belly] Handshake version mismatch (got {num}, expected {1}) - mod disabled");
					FullBellyManager.instance?.ResetFullBelly("Invalid handshake");
				}
			}
			else
			{
				isHandshakeValid = false;
				Logger.LogWarning((object)"[Full Belly] Handshake failed - host does not have the mod. Full Belly functionality disabled for anti-cheat.");
				FullBellyManager.instance?.ResetFullBelly("Invalid handshake");
			}
		}
		catch (Exception ex3)
		{
			Logger.LogWarning((object)("[Full Belly] Failed to check room properties as client: " + ex3.Message));
			isHandshakeValid = false;
		}
	}

	internal void ApplyConfigFromRoomProperties(Hashtable roomProps)
	{
		try
		{
			if (!((Dictionary<object, object>)(object)roomProps).ContainsKey((object)"FullBellyHandshake"))
			{
				isHandshakeValid = false;
				Logger.LogWarning((object)"[Full Belly] Handshake missing in room properties - mod disabled");
				FullBellyManager.instance?.ResetFullBelly("Invalid handshake");
				return;
			}
			int num = (int)roomProps[(object)"FullBellyHandshake"];
			isHandshakeValid = num == 1;
			if (!isHandshakeValid)
			{
				Logger.LogWarning((object)$"[Full Belly] Handshake version mismatch (got {num}, expected {1}) - mod disabled");
				FullBellyManager.instance?.ResetFullBelly("Invalid handshake");
			}
			else
			{
				if (!((Dictionary<object, object>)(object)roomProps).ContainsKey((object)"FullBellyConfig_Threshold"))
				{
					return;
				}
				syncedFullnessThreshold = (float)roomProps[(object)"FullBellyConfig_Threshold"];
				syncedFullnessDecayInterval = (float)roomProps[(object)"FullBellyConfig_FullnessDecayInterval"];
				syncedFullnessDecayAmount = (float)roomProps[(object)"FullBellyConfig_FullnessDecayAmount"];
				syncedBloatedDecayInterval = (float)roomProps[(object)"FullBellyConfig_BloatedDecayInterval"];
				syncedBloatedDecayAmount = (float)roomProps[(object)"FullBellyConfig_BloatedDecayAmount"];
				syncedEnableOvereating = (bool)roomProps[(object)"FullBellyConfig_EnableOvereating"];
				syncedEnableFarting = (bool)roomProps[(object)"FullBellyConfig_EnableFarting"];
				syncedFartChance = (float)roomProps[(object)"FullBellyConfig_FartChance"];
				syncedDecayFartChance = (float)roomProps[(object)"FullBellyConfig_DecayFartChance"];
				FullBellyManager.instance?.UpdateSyncedThreshold(syncedFullnessThreshold);
				Logger.LogInfo((object)$"[Full Belly] Updated FullBellyManager threshold to {syncedFullnessThreshold * 100f:0.00}%");
				if (!syncedEnableOvereating && (Object)(object)FullBellyManager.instance != (Object)null)
				{
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter?.refs?.afflictions != (Object)null)
					{
						FullBellyManager.instance.UpdateBloatedStatus(localCharacter.refs.afflictions);
					}
				}
				Logger.LogInfo((object)$"[Full Belly] Applied config from room properties - Threshold: {syncedFullnessThreshold * 100f:0.00}%");
			}
		}
		catch (Exception ex)
		{
			Logger.LogWarning((object)("[Full Belly] Failed to apply config from room properties: " + ex.Message));
			isHandshakeValid = false;
		}
	}

	[IteratorStateMachine(typeof(<RetryConfigSyncCoroutine>d__43))]
	internal IEnumerator RetryConfigSyncCoroutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <RetryConfigSyncCoroutine>d__43(0)
		{
			<>4__this = this
		};
	}

	private void Update()
	{
		bool isConnectedAndReady = PhotonNetwork.IsConnectedAndReady;
		bool isMasterClient = PhotonNetwork.IsMasterClient;
		bool inRoom = PhotonNetwork.InRoom;
		if (isConnectedAndReady && !wasConnectedAndReady)
		{
			Logger.LogInfo((object)"[Full Belly] PhotonNetwork became connected and ready - triggering sync");
			AttemptConfigSync(forceSync: true);
		}
		if (!inRoom && wasInRoom)
		{
			Logger.LogInfo((object)"[Full Belly] Left room - invalidating handshake");
			isHandshakeValid = false;
		}
		if (inRoom && !wasInRoom)
		{
			Logger.LogInfo((object)"[Full Belly] Joined room - triggering sync and handshake check");
			isHandshakeValid = false;
			AttemptConfigSync(forceSync: true);
		}
		if (isMasterClient && !wasMasterClient)
		{
			Logger.LogInfo((object)"[Full Belly] Became master client - triggering sync");
			isHandshakeValid = true;
			AttemptConfigSync(forceSync: true);
		}
		wasConnectedAndReady = isConnectedAndReady;
		wasMasterClient = isMasterClient;
		wasInRoom = inRoom;
	}

	[PunRPC]
	public void SyncHostSettings(float fullnessThreshold, float fullnessDecayInterval, float fullnessDecayAmount, float bloatedDecayInterval, float bloatedDecayAmount, bool enableOvereating, bool enableFarting, float fartChance, float decayFartChance)
	{
		isHandshakeValid = true;
		syncedFullnessThreshold = fullnessThreshold;
		syncedFullnessDecayInterval = fullnessDecayInterval;
		syncedFullnessDecayAmount = fullnessDecayAmount;
		syncedBloatedDecayInterval = bloatedDecayInterval;
		syncedBloatedDecayAmount = bloatedDecayAmount;
		syncedEnableOvereating = enableOvereating;
		syncedEnableFarting = enableFarting;
		syncedFartChance = fartChance;
		syncedDecayFartChance = decayFartChance;
		FullBellyManager.instance?.UpdateSyncedThreshold(syncedFullnessThreshold);
		Logger.LogInfo((object)$"[Full Belly] Updated FullBellyManager threshold to {syncedFullnessThreshold * 100f:0.00}%");
		Logger.LogInfo((object)$"[Full Belly] Received synced config from host - Handshake valid - Threshold: {syncedFullnessThreshold * 100f:0.00}%");
	}
}
internal static class SpriteLoader
{
	public static Sprite FromEmbedded(string resourceName, float pixelsPerUnit = 100f)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				Debug.LogError((object)("[Full Belly] Embedded resource not found: " + resourceName));
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
			{
				Debug.LogError((object)("[Full Belly] Failed to load image data for: " + resourceName));
				return null;
			}
			((Object)val).name = Path.GetFileNameWithoutExtension(resourceName);
			((Texture)val).filterMode = (FilterMode)1;
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), pixelsPerUnit);
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("[Full Belly] Error loading sprite " + resourceName + ": " + ex.Message));
			return null;
		}
	}
}
public static class BloatedAffliction
{
	[CompilerGenerated]
	private sealed class <CreateBarAfflictionComponent>d__11 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public ManualLogSource logger;

		private StaminaBar <staminaBar>5__1;

		private int <attempts>5__2;

		private BarAffliction[] <existingAfflictions>5__3;

		private BarAffliction <template>5__4;

		private GameObject <newAfflictionObj>5__5;

		private BarAffliction <newAffliction>5__6;

		private bool <colorSet>5__7;

		private Transform <staminaInfoChild>5__8;

		private BarAffliction[] <>s__9;

		private int <>s__10;

		private BarAffliction <aff>5__11;

		private Type <statusContentType>5__12;

		private FieldInfo <registeredStatusesField>5__13;

		private IList <registeredList>5__14;

		private IEnumerator <>s__15;

		private object <item>5__16;

		private PropertyInfo <contentProp>5__17;

		private object <wrappedContent>5__18;

		private PropertyInfo <statusProp>5__19;

		private object <status>5__20;

		private PropertyInfo <typeProp>5__21;

		private object <statusType>5__22;

		private PropertyInfo <iconProp>5__23;

		private PropertyInfo <colorProp>5__24;

		private Sprite <iconSprite>5__25;

		private Color <statusColor>5__26;

		private Image[] <allImages>5__27;

		private Image[] <>s__28;

		private int <>s__29;

		private Image <img>5__30;

		private string <imgName>5__31;

		private Color <currentColor>5__32;

		private Exception <ex>5__33;

		private Image[] <allImages>5__34;

		private Sprite <customPatternSprite>5__35;

		private Exception <ex>5__36;

		private Image[] <>s__37;

		private int <>s__38;

		private Image <img>5__39;

		private string <imgNameLower>5__40;

		private bool <isPattern>5__41;

		private bool <isFill>5__42;

		private PropertyInfo <imageTypeProp>5__43;

		private Type <enumType>5__44;

		private object <tiledValue>5__45;

		private Exception <ex>5__46;

		private FieldInfo <afflictionsField>5__47;

		private BarAffliction[] <refreshedAfflictions>5__48;

		private Exception <ex>5__49;

		private Exception <ex>5__50;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<staminaBar>5__1 = null;
			<existingAfflictions>5__3 = null;
			<template>5__4 = null;
			<newAfflictionObj>5__5 = null;
			<newAffliction>5__6 = null;
			<staminaInfoChild>5__8 = null;
			<>s__9 = null;
			<aff>5__11 = null;
			<statusContentType>5__12 = null;
			<registeredStatusesField>5__13 = null;
			<registeredList>5__14 = null;
			<>s__15 = null;
			<item>5__16 = null;
			<contentProp>5__17 = null;
			<wrappedContent>5__18 = null;
			<statusProp>5__19 = null;
			<status>5__20 = null;
			<typeProp>5__21 = null;
			<statusType>5__22 = null;
			<iconProp>5__23 = null;
			<colorProp>5__24 = null;
			<iconSprite>5__25 = null;
			<allImages>5__27 = null;
			<>s__28 = null;
			<img>5__30 = null;
			<imgName>5__31 = null;
			<ex>5__33 = null;
			<allImages>5__34 = null;
			<customPatternSprite>5__35 = null;
			<ex>5__36 = null;
			<>s__37 = null;
			<img>5__39 = null;
			<imgNameLower>5__40 = null;
			<imageTypeProp>5__43 = null;
			<enumType>5__44 = null;
			<tiledValue>5__45 = null;
			<ex>5__46 = null;
			<afflictionsField>5__47 = null;
			<refreshedAfflictions>5__48 = null;
			<ex>5__49 = null;
			<ex>5__50 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_07af: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b74: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a27: Unknown result type (might be due to invalid IL or missing references)
			//IL_0421: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_064e: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<staminaBar>5__1 = null;
				<attempts>5__2 = 0;
				break;
			case 2:
				<>1__state = -1;
				<attempts>5__2++;
				break;
			}
			while ((Object)(object)<staminaBar>5__1 == (Object)null && <attempts>5__2 < 1)
			{
				<staminaBar>5__1 = Object.FindFirstObjectByType<StaminaBar>((FindObjectsInactive)0);
				if ((Object)(object)<staminaBar>5__1 == (Object)null)
				{
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				}
			}
			if ((Object)(object)<staminaBar>5__1 == (Object)null)
			{
				ManualLogSource obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"[Full Belly] Could not find StaminaBar after waiting - cannot create BarAffliction component");
				}
				return false;
			}
			<existingAfflictions>5__3 = ((Component)<staminaBar>5__1).GetComponentsInChildren<BarAffliction>(true);
			if (<existingAfflictions>5__3 == null || <existingAfflictions>5__3.Length == 0)
			{
				ManualLogSource obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogError((object)"[Full Belly] Failed to create Bloated Affliction: No existing BarAffliction components found");
				}
				return false;
			}
			<>s__9 = <existingAfflictions>5__3;
			for (<>s__10 = 0; <>s__10 < <>s__9.Length; <>s__10++)
			{
				<aff>5__11 = <>s__9[<>s__10];
				if (<aff>5__11.afflictionType == BloatedType)
				{
					return false;
				}
				<aff>5__11 = null;
			}
			<>s__9 = null;
			<template>5__4 = <existingAfflictions>5__3[0];
			<newAfflictionObj>5__5 = Object.Instantiate<GameObject>(((Component)<template>5__4).gameObject, ((Component)<template>5__4).transform.parent);
			((Object)<newAfflictionObj>5__5).name = "BarAffliction_Bloated";
			<newAffliction>5__6 = <newAfflictionObj>5__5.GetComponent<BarAffliction>();
			if ((Object)(object)<newAffliction>5__6 == (Object)null)
			{
				ManualLogSource obj3 = logger;
				if (obj3 != null)
				{
					obj3.LogError((object)"[Full Belly] Failed to get BarAffliction component from instantiated GameObject");
				}
				Object.Destroy((Object)(object)<newAfflictionObj>5__5);
				return false;
			}
			<newAffliction>5__6.afflictionType = BloatedType;
			try
			{
				<statusContentType>5__12 = AccessTools.TypeByName("PEAKLib.Stats.StatusContent");
				if (<statusContentType>5__12 != null)
				{
					<registeredStatusesField>5__13 = <statusContentType>5__12.GetField("s_RegisteredStatuses", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					if (<registeredStatusesField>5__13 != null)
					{
						object value = <registeredStatusesField>5__13.GetValue(null);
						<registeredList>5__14 = value as IList;
						if (<registeredList>5__14 != null)
						{
							<>s__15 = <registeredList>5__14.GetEnumerator();
							try
							{
								while (<>s__15.MoveNext())
								{
									<item>5__16 = <>s__15.Current;
									if (<item>5__16 != null)
									{
										<contentProp>5__17 = <item>5__16.GetType().GetProperty("Content", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
										if (<contentProp>5__17 != null)
										{
											<wrappedContent>5__18 = <contentProp>5__17.GetValue(<item>5__16);
											<statusProp>5__19 = <wrappedContent>5__18?.GetType().GetProperty("Status") ?? <wrappedContent>5__18?.GetType().GetProperty("StatusContent");
											if (<statusProp>5__19 != null)
											{
												<status>5__20 = <statusProp>5__19.GetValue(<wrappedContent>5__18);
												<typeProp>5__21 = <status>5__20?.GetType().GetProperty("Type");
												if (<typeProp>5__21 != null)
												{
													<statusType>5__22 = <typeProp>5__21.GetValue(<status>5__20);
													if (<statusType>5__22 != null && <statusType>5__22.Equals(BloatedType))
													{
														<iconProp>5__23 = <status>5__20.GetType().GetProperty("Icon");
														<colorProp>5__24 = <status>5__20.GetType().GetProperty("Color");
														if (<iconProp>5__23 != null && (Object)(object)<newAffliction>5__6.icon != (Object)null)
														{
															ref Sprite reference = ref <iconSprite>5__25;
															object? value2 = <iconProp>5__23.GetValue(<status>5__20);
															reference = (Sprite)((value2 is Sprite) ? value2 : null);
															if ((Object)(object)<iconSprite>5__25 != (Object)null)
															{
																<newAffliction>5__6.icon.sprite = <iconSprite>5__25;
															}
															<iconSprite>5__25 = null;
														}
														if (!(<colorProp>5__24 != null))
														{
															break;
														}
														<statusColor>5__26 = (Color)<colorProp>5__24.GetValue(<status>5__20);
														if ((Object)(object)<newAffliction>5__6.icon != (Object)null)
														{
															((Graphic)<newAffliction>5__6.icon).color = IconColor;
														}
														if ((Object)(object)<newAffliction>5__6.rtf != (Object)null)
														{
															<allImages>5__27 = ((Component)<newAffliction>5__6.rtf).GetComponentsInChildren<Image>(true);
															<>s__28 = <allImages>5__27;
															for (<>s__29 = 0; <>s__29 < <>s__28.Length; <>s__29++)
															{
																<img>5__30 = <>s__28[<>s__29];
																if (!((Object)(object)<img>5__30 == (Object)(object)<newAffliction>5__6.icon))
																{
																	<imgName>5__31 = ((Object)((Component)<img>5__30).gameObject).name.ToLower();
																	<currentColor>5__32 = ((Graphic)<img>5__30).color;
																	if (<imgName>5__31.Contains("shadow") || <imgName>5__31.Contains("pattern") || <imgName>5__31.Contains("overlay") || <imgName>5__31.Contains("strip"))
																	{
																		((Graphic)<img>5__30).color = PatternOverlayColor;
																	}
																	else
																	{
																		((Graphic)<img>5__30).color = FillColor;
																	}
																	<imgName>5__31 = null;
																	<img>5__30 = null;
																}
															}
															<>s__28 = null;
															<allImages>5__27 = null;
														}
														else
														{
															ManualLogSource obj4 = logger;
															if (obj4 != null)
															{
																obj4.LogWarning((object)"[Full Belly] BarAffliction rtf is null, cannot set bar color");
															}
														}
														break;
													}
													<statusType>5__22 = null;
												}
												<status>5__20 = null;
												<typeProp>5__21 = null;
											}
											<wrappedContent>5__18 = null;
											<statusProp>5__19 = null;
										}
										<contentProp>5__17 = null;
									}
									<item>5__16 = null;
								}
							}
							finally
							{
								if (<>s__15 is IDisposable disposable)
								{
									disposable.Dispose();
								}
							}
							<>s__15 = null;
						}
						<registeredList>5__14 = null;
					}
					<registeredStatusesField>5__13 = null;
				}
				<statusContentType>5__12 = null;
			}
			catch (Exception ex)
			{
				<ex>5__33 = ex;
				ManualLogSource obj5 = logger;
				if (obj5 != null)
				{
					obj5.LogWarning((object)("[Full Belly] Could not set icon/color from PEAKLib registry: " + <ex>5__33.Message));
				}
			}
			<colorSet>5__7 = false;
			if ((Object)(object)<newAffliction>5__6.icon != (Object)null)
			{
				((Graphic)<newAffliction>5__6.icon).color = IconColor;
			}
			if ((Object)(object)<newAffliction>5__6.rtf != (Object)null)
			{
				<allImages>5__34 = ((Component)<newAffliction>5__6.rtf).GetComponentsInChildren<Image>(true);
				<customPatternSprite>5__35 = null;
				if (!string.IsNullOrEmpty(CustomPatternSpriteResource))
				{
					try
					{
						<customPatternSprite>5__35 = SpriteLoader.FromEmbedded(CustomPatternSpriteResource, PatternPixelsPerUnit);
						if (!((Object)(object)<customPatternSprite>5__35 != (Object)null))
						{
							ManualLogSource obj6 = logger;
							if (obj6 != null)
							{
								obj6.LogWarning((object)("[Full Belly] Failed to load custom pattern sprite from '" + CustomPatternSpriteResource + "' - will use default"));
							}
						}
					}
					catch (Exception ex)
					{
						<ex>5__36 = ex;
						ManualLogSource obj7 = logger;
						if (obj7 != null)
						{
							obj7.LogWarning((object)("[Full Belly] Error loading custom pattern sprite: " + <ex>5__36.Message));
						}
					}
				}
				<>s__37 = <allImages>5__34;
				for (<>s__38 = 0; <>s__38 < <>s__37.Length; <>s__38++)
				{
					<img>5__39 = <>s__37[<>s__38];
					if (!((Object)(object)<img>5__39 == (Object)(object)<newAffliction>5__6.icon))
					{
						<imgNameLower>5__40 = ((Object)((Component)<img>5__39).gameObject).name.ToLower();
						<isPattern>5__41 = <imgNameLower>5__40.Contains("shadow") || <imgNameLower>5__40.Contains("pattern") || <imgNameLower>5__40.Contains("overlay") || <imgNameLower>5__40.Contains("strip") || <imgNameLower>5__40.Contains("diagonal") || <imgNameLower>5__40.Contains("line");
						<isFill>5__42 = (Object)(object)((Component)<img>5__39).gameObject == (Object)(object)((Component)<newAffliction>5__6.rtf).gameObject || <imgNameLower>5__40.Contains("fill") || <imgNameLower>5__40.Contains("background") || <imgNameLower>5__40.Contains("bar") || <imgNameLower>5__40.Contains("base");
						if (<isPattern>5__41)
						{
							((Graphic)<img>5__39).color = PatternOverlayColor;
							<colorSet>5__7 = true;
						}
						else if (<isFill>5__42)
						{
							((Graphic)<img>5__39).color = FillColor;
							if ((Object)(object)<customPatternSprite>5__35 != (Object)null && <imgNameLower>5__40.Contains("fill"))
							{
								<img>5__39.sprite = <customPatternSprite>5__35;
								try
								{
									<imageTypeProp>5__43 = typeof(Image).GetProperty("type");
									if (<imageTypeProp>5__43 != null)
									{
										<enumType>5__44 = <imageTypeProp>5__43.PropertyType;
										<tiledValue>5__45 = Enum.GetValues(<enumType>5__44).Cast<object>().FirstOrDefault((object v) => v.ToString() == "Tiled");
										if (<tiledValue>5__45 != null)
										{
											<imageTypeProp>5__43.SetValue(<img>5__39, <tiledValue>5__45);
										}
										<enumType>5__44 = null;
										<tiledValue>5__45 = null;
									}
									<imageTypeProp>5__43 = null;
								}
								catch (Exception ex)
								{
									<ex>5__46 = ex;
									ManualLogSource obj8 = logger;
									if (obj8 != null)
									{
										obj8.LogWarning((object)("[Full Belly] Failed to set Image Type to Tiled: " + <ex>5__46.Message));
									}
								}
							}
							<colorSet>5__7 = true;
						}
						else
						{
							((Graphic)<img>5__39).color = FillColor;
							<colorSet>5__7 = true;
						}
						<imgNameLower>5__40 = null;
						<img>5__39 = null;
					}
				}
				<>s__37 = null;
				if (!<colorSet>5__7)
				{
					ManualLogSource obj9 = logger;
					if (obj9 != null)
					{
						obj9.LogWarning((object)"[Full Belly] Could not find any Image components for bar color on BarAffliction rtf or children!");
					}
				}
				<allImages>5__34 = null;
				<customPatternSprite>5__35 = null;
			}
			else
			{
				ManualLogSource obj10 = logger;
				if (obj10 != null)
				{
					obj10.LogWarning((object)"[Full Belly] BarAffliction rtf is null, cannot set bar color");
				}
			}
			<newAfflictionObj>5__5.SetActive(true);
			try
			{
				<afflictionsField>5__47 = typeof(StaminaBar).GetField("afflictions", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (<afflictionsField>5__47 != null)
				{
					<refreshedAfflictions>5__48 = ((Component)<staminaBar>5__1).GetComponentsInChildren<BarAffliction>(true);
					<afflictionsField>5__47.SetValue(<staminaBar>5__1, <refreshedAfflictions>5__48);
					<refreshedAfflictions>5__48 = null;
				}
				<staminaBar>5__1.ChangeBar();
				<afflictionsField>5__47 = null;
			}
			catch (Exception ex)
			{
				<ex>5__49 = ex;
				ManualLogSource obj11 = logger;
				if (obj11 != null)
				{
					obj11.LogWarning((object)("[Full Belly] Failed to refresh StaminaBar afflictions array: " + <ex>5__49.Message));
				}
			}
			<staminaInfoChild>5__8 = <newAfflictionObj>5__5.transform.Find("StaminaInfo");
			if ((Object)(object)<staminaInfoChild>5__8 != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)<staminaInfoChild>5__8).gameObject);
			}
			try
			{
				RegisterWithStaminaInfoForked(<staminaBar>5__1, <newAffliction>5__6, logger);
			}
			catch (Exception ex)
			{
				<ex>5__50 = ex;
				ManualLogSource obj12 = logger;
				if (obj12 != null)
				{
					obj12.LogDebug((object)("[Full Belly] Could not register with StaminaInfoForked: " + <ex>5__50.Message));
				}
			}
			ManualLogSource obj13 = logger;
			if (obj13 != null)
			{
				obj13.LogInfo((object)"[Full Belly] Bloated Affliction Created");
			}
			return false;
		}

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

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

	public const string StatusName = "Bloated";

	public static STATUSTYPE BloatedType;

	private static bool isRegistered = false;

	private static BaseUnityPlugin cachedPluginInstance = null;

	public static readonly Color FillColor = new Color(1f, 0.5f, 0.8f, 1f);

	public static readonly Color PatternOverlayColor = new Color(1f, 0.7f, 0.9f, 0.6f);

	public static readonly Color IconColor = new Color(1f, 0.9f, 1f, 1f);

	public static readonly string CustomPatternSpriteResource = "FullBellyMod.Sprites.CheckeredOverlay.png";

	public static readonly float PatternPixelsPerUnit = 25f;

	public static void CreateBloatedAffliction(ManualLogSource logger, BaseUnityPlugin pluginInstance)
	{
		//IL_0b91: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b97: Invalid comparison between Unknown and I4
		//IL_0c51: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c57: Invalid comparison between Unknown and I4
		//IL_0b99: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b9f: Invalid comparison between Unknown and I4
		//IL_0c59: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c5f: Invalid comparison between Unknown and I4
		//IL_0961: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ae0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c8d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c78: Unknown result type (might be due to invalid IL or missing references)
		//IL_0aac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ab1: Unknown result type (might be due to invalid IL or missing references)
		if (isRegistered)
		{
			logger.LogInfo((object)"[Full Belly] Bloated affliction already registered, skipping.");
			return;
		}
		if (logger == null)
		{
			Debug.LogError((object)"[Full Belly] Logger is null!");
			return;
		}
		if ((Object)(object)pluginInstance == (Object)null)
		{
			logger.LogError((object)"[Full Belly] PluginInstance is null! Cannot register affliction.");
			return;
		}
		try
		{
			Type type = AccessTools.TypeByName("PEAKLib.Stats.Status");
			Type type2 = AccessTools.TypeByName("PEAKLib.Core.ModDefinition");
			Type type3 = AccessTools.TypeByName("PEAKLib.Stats.StatusContent") ?? AccessTools.TypeByName("PEAKLib.Core.StatusContent") ?? AccessTools.TypeByName("PEAKLib.UI.StatusContent") ?? AccessTools.TypeByName("com.github.PEAKModding.PEAKLib.Stats.StatusContent") ?? AccessTools.TypeByName("com.github.PEAKModding.PEAKLib.Core.StatusContent");
			if (type3 == null)
			{
				List<string> list = new List<string>();
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					try
					{
						Type type4 = assembly.GetType("PEAKLib.Stats.StatusContent") ?? assembly.GetType("PEAKLib.Core.StatusContent") ?? assembly.GetType("PEAKLib.UI.StatusContent");
						if (type4 != null)
						{
							type3 = type4;
							break;
						}
						Type[] types = assembly.GetTypes();
						foreach (Type type5 in types)
						{
							if (type5.Name.Contains("StatusContent"))
							{
								list.Add(type5.FullName + " (in " + assembly.GetName().Name + ")");
							}
						}
						continue;
					}
					catch
					{
						continue;
					}
				}
				if (list.Count <= 0)
				{
				}
			}
			if (type3 == null)
			{
				logger.LogWarning((object)"[Full Belly] StatusContent NOT FOUND - will use Weight fallback");
			}
			if (type != null && type3 != null && type2 != null)
			{
				List<MethodInfo> list2 = (from m in AccessTools.GetDeclaredMethods(type2)
					where m.Name == "GetOrCreate"
					select m).ToList();
				if (list2.Count == 0)
				{
					logger.LogError((object)"[Full Belly] No GetOrCreate methods found in ModDefinition!");
					throw new Exception("ModDefinition.GetOrCreate method not found");
				}
				BepInPlugin val = ((MemberInfo)typeof(FullBellyPlugin)).GetCustomAttribute<BepInPlugin>() ?? typeof(FullBellyPlugin).Assembly.GetCustomAttribute<BepInPlugin>();
				string text = "tony4twentys.full_belly";
				string text2 = "Full Belly";
				Version version = new Version(3, 1, 1);
				if (val != null)
				{
					text = val.GUID;
					text2 = val.Name;
					version = val.Version;
				}
				else
				{
					logger.LogWarning((object)"[Full Belly] BepInPlugin attribute not found, using hardcoded values");
				}
				MethodInfo methodInfo = list2.FirstOrDefault((MethodInfo m) => m.GetParameters().Length == 3) ?? list2.FirstOrDefault((MethodInfo m) => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(BepInPlugin)) ?? list2.FirstOrDefault((MethodInfo m) => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(string)) ?? list2.FirstOrDefault((MethodInfo m) => m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType.Name.Contains("PluginInfo")) ?? list2.First();
				PropertyInfo propertyInfo = AccessTools.Property(typeof(BaseUnityPlugin), "Info");
				object obj2 = null;
				object obj3 = null;
				if (propertyInfo != null && (Object)(object)pluginInstance != (Object)null)
				{
					try
					{
						obj2 = propertyInfo.GetValue(pluginInstance);
						if (obj2 != null)
						{
							PropertyInfo propertyInfo2 = AccessTools.Property(obj2.GetType(), "Metadata");
							if (propertyInfo2 != null)
							{
								obj3 = propertyInfo2.GetValue(obj2);
							}
						}
					}
					catch (Exception ex)
					{
						logger.LogWarning((object)("[Full Belly] Error getting Info property: " + ex.Message));
					}
				}
				else
				{
					logger.LogWarning((object)"[Full Belly] Info property or pluginInstance is null!");
				}
				Type type6 = AccessTools.TypeByName("BepInEx.PluginInfo.Metadata") ?? AccessTools.TypeByName("BepInEx.PluginInfo+Metadata") ?? AccessTools.TypeByName("PEAKLib.Core.ModDefinition+Metadata");
				object obj4 = null;
				if (obj2 != null)
				{
					PropertyInfo propertyInfo3 = AccessTools.Property(obj2.GetType(), "Metadata");
					obj4 = ((!(propertyInfo3 != null)) ? obj2 : propertyInfo3.GetValue(obj2));
				}
				else
				{
					logger.LogWarning((object)"[Full Belly] PluginInfo is null");
				}
				if (obj4 == null && type6 != null)
				{
					logger.LogInfo((object)("[Full Belly] Attempting to create Metadata from constructor (type: " + type6.FullName + ")..."));
					ConstructorInfo constructorInfo = AccessTools.Constructor(type6, new Type[3]
					{
						typeof(string),
						typeof(string),
						typeof(string)
					}, false);
					if (constructorInfo != null)
					{
						obj4 = constructorInfo.Invoke(new object[3]
						{
							text,
							text2,
							version.ToString()
						});
						logger.LogInfo((object)("[Full Belly] ✓ Metadata created from constructor: " + (obj4?.GetType().FullName ?? "null")));
					}
					else
					{
						logger.LogWarning((object)"[Full Belly] Metadata constructor not found");
					}
				}
				object obj5 = null;
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length == 3)
				{
					try
					{
						obj5 = methodInfo.Invoke(null, new object[3] { text, text2, version });
					}
					catch (Exception ex2)
					{
						logger.LogError((object)("[Full Belly] GetOrCreate(GUID, Name, Version) failed: " + ex2.Message));
					}
				}
				else if (parameters.Length != 1)
				{
					obj5 = ((obj4 == null) ? methodInfo.Invoke(null, new object[1] { text }) : methodInfo.Invoke(null, new object[1] { obj4 }));
				}
				else
				{
					Type parameterType = parameters[0].ParameterType;
					if (obj3 != null && (parameterType.IsAssignableFrom(obj3.GetType()) || parameterType.IsInstanceOfType(obj3)))
					{
						try
						{
							obj5 = methodInfo.Invoke(null, new object[1] { obj3 });
						}
						catch (Exception ex3)
						{
							logger.LogWarning((object)("[Full Belly] Failed to call GetOrCreate with Info.Metadata: " + ex3.Message));
						}
					}
					else if (obj3 != null)
					{
						try
						{
							obj5 = methodInfo.Invoke(null, new object[1] { obj3 });
						}
						catch (Exception ex4)
						{
							logger.LogWarning((object)("[Full Belly] Failed (expected): " + ex4.Message));
						}
					}
					if (obj5 == null && obj2 != null && (parameterType.IsAssignableFrom(obj2.GetType()) || parameterType.IsInstanceOfType(obj2)))
					{
						try
						{
							obj5 = methodInfo.Invoke(null, new object[1] { obj2 });
						}
						catch (Exception ex5)
						{
							logger.LogWarning((object)("[Full Belly] Failed to call GetOrCreate with PluginInfo: " + ex5.Message));
						}
					}
					if (obj5 == null && obj4 != null && (parameterType.IsAssignableFrom(obj4.GetType()) || parameterType.IsInstanceOfType(obj4)))
					{
						obj5 = methodInfo.Invoke(null, new object[1] { obj4 });
					}
					else if (parameterType == typeof(string))
					{
						obj5 = methodInfo.Invoke(null, new object[1] { text });
					}
					else if (parameterType == typeof(BepInPlugin))
					{
						if (val != null)
						{
							obj5 = methodInfo.Invoke(null, new object[1] { val });
						}
						else
						{
							logger.LogWarning((object)"[Full Belly] Cannot use BepInPlugin parameter - attribute is null");
						}
					}
				}
				if (obj5 == null && parameters.Length != 3)
				{
					MethodInfo methodInfo2 = list2.FirstOrDefault((MethodInfo m) => m.GetParameters().Length == 3);
					if (methodInfo2 != null)
					{
						try
						{
							obj5 = methodInfo2.Invoke(null, new object[3] { text, text2, version });
						}
						catch (Exception ex6)
						{
							logger.LogError((object)("[Full Belly] Fallback GetOrCreate also failed: " + ex6.Message));
						}
					}
				}
				if (obj5 == null)
				{
					logger.LogError((object)"[Full Belly] Failed to get or create ModDefinition with all methods!");
					throw new Exception("Failed to get or create ModDefinition");
				}
				Sprite val2 = SpriteLoader.FromEmbedded("FullBellyMod.Sprites.BloatedIcon.png");
				if ((Object)(object)val2 == (Object)null)
				{
					logger.LogWarning((object)"[Full Belly] Embedded sprite not found, creating placeholder pink square.");
					val2 = CreatePlaceholderSprite();
				}
				object obj6 = Activator.CreateInstance(type);
				AccessTools.Property(type, "Name")?.SetValue(obj6, "Bloated");
				Color val3 = default(Color);
				((Color)(ref val3))..ctor(1f, 0.5f, 0.8f, 1f);
				AccessTools.Property(type, "Color")?.SetValue(obj6, val3);
				AccessTools.Property(type, "MaxAmount")?.SetValue(obj6, 2f);
				AccessTools.Property(type, "AllowClear")?.SetValue(obj6, true);
				AccessTools.Property(type, "ReductionCooldown")?.SetValue(obj6, 0f);
				AccessTools.Property(type, "ReductionPerSecond")?.SetValue(obj6, 0f);
				AccessTools.Property(type, "Icon")?.SetValue(obj6, val2);
				object obj7 = Activator.CreateInstance(type3, obj6);
				MethodInfo methodInfo3 = AccessTools.Method(type3, "Register", (Type[])null, (Type[])null);
				if (methodInfo3 == null)
				{
					logger.LogError((object)"[Full Belly] Failed to find StatusContent.Register method!");
					throw new Exception("StatusContent.Register method not found");
				}
				methodInfo3.Invoke(obj7, new object[1] { obj5 });
				PropertyInfo propertyInfo4 = AccessTools.Property(type, "Type");
				if (propertyInfo4 == null)
				{
					logger.LogError((object)"[Full Belly] Failed to find Status.Type property!");
					throw new Exception("Status.Type property not found");
				}
				BloatedType = (STATUSTYPE)propertyInfo4.GetValue(obj6);
				cachedPluginInstance = pluginInstance;
				isRegistered = true;
			}
			else
			{
				logger.LogWarning((object)"[Full Belly] ===== PEAKLib NOT FOUND - Using Weight status as fallback =====");
				logger.LogWarning((object)"[Full Belly] To use custom Bloated affliction, add PEAKLib.Core and PEAKLib.Stats references.");
				BloatedType = (STATUSTYPE)7;
				isRegistered = true;
			}
		}
		catch (Exception ex7)
		{
			bool flag = false;
			if (ex7.InnerException != null)
			{
				string text3 = ex7.InnerException.Message ?? "";
				if (text3.Contains("already registered") || text3.Contains("already exists"))
				{
					flag = true;
				}
			}
			else if (ex7.Message != null && (ex7.Message.Contains("already registered") || ex7.Message.Contains("already exists")))
			{
				flag = true;
			}
			if (flag)
			{
				if ((int)BloatedType == 7 || (int)BloatedType == 0)
				{
					logger.LogWarning((object)"[Full Belly] BloatedType not set, attempting to retrieve from registry...");
				}
				cachedPluginInstance = pluginInstance;
				isRegistered = true;
				return;
			}
			logger.LogError((object)"[Full Belly] ===== ERROR CREATING BLOATED AFFLICTION =====");
			logger.LogError((object)("[Full Belly] Error: " + ex7.Message));
			logger.LogError((object)("[Full Belly] Type: " + ex7.GetType().FullName));
			if (ex7.InnerException != null)
			{
				logger.LogError((object)("[Full Belly] Inner Exception: " + ex7.InnerException.Message));
			}
			logger.LogError((object)("[Full Belly] Stack trace: " + ex7.StackTrace));
			if ((int)BloatedType == 7 || (int)BloatedType == 0)
			{
				logger.LogWarning((object)"[Full Belly] Falling back to Weight status (only on initial registration failure)");
				BloatedType = (STATUSTYPE)7;
				isRegistered = true;
			}
			else
			{
				logger.LogInfo((object)$"[Full Belly] Keeping existing BloatedType ({BloatedType}) despite registration error");
				isRegistered = true;
			}
		}
	}

	private static string GetGameObjectPath(GameObject obj)
	{
		if ((Object)(object)obj == (Object)null)
		{
			return "null";
		}
		string text = ((Object)obj).name;
		Transform parent = obj.transform.parent;
		while ((Object)(object)parent != (Object)null)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		return text;
	}

	[IteratorStateMachine(typeof(<CreateBarAfflictionComponent>d__11))]
	public static IEnumerator CreateBarAfflictionComponent(ManualLogSource logger)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <CreateBarAfflictionComponent>d__11(0)
		{
			logger = logger
		};
	}

	private static void RegisterWithStaminaInfoForked(StaminaBar staminaBar, BarAffliction bloatedAffliction, ManualLogSource logger)
	{
		if ((Object)(object)staminaBar == (Object)null || (Object)(object)bloatedAffliction == (Object)null)
		{
			return;
		}
		Type type = AccessTools.TypeByName("StaminaInfo.Plugin");
		if (type == null)
		{
			return;
		}
		FullBellyPlugin.isStaminaInfoForkedDetected = true;
		MethodInfo method = type.GetMethod("AddTextObject", BindingFlags.Static | BindingFlags.NonPublic);
		if (method == null)
		{
			if (logger != null)
			{
				logger.LogDebug((object)"[Full Belly] Could not find AddTextObject method in StaminaInfoForked");
			}
			return;
		}
		ParameterInfo[] parameters = method.GetParameters();
		if (parameters.Length != 2 || parameters[0].ParameterType != typeof(GameObject) || parameters[1].ParameterType != typeof(string))
		{
			if (logger != null)
			{
				logger.LogDebug((object)"[Full Belly] AddTextObject method signature doesn't match expected format");
			}
			return;
		}
		try
		{
			string name = ((Object)((Component)bloatedAffliction).gameObject).name;
			method.Invoke(null, new object[2]
			{
				((Component)bloatedAffliction).gameObject,
				name
			});
			if (logger != null)
			{
				logger.LogInfo((object)"[Full Belly] Registered Bloated BarAffliction with StaminaInfoForked");
			}
		}
		catch (Exception ex)
		{
			if (logger != null)
			{
				logger.LogDebug((object)("[Full Belly] Failed to register with StaminaInfoForked: " + ex.Message));
			}
		}
	}

	private static Sprite CreatePlaceholderSprite()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Expected O, but got Unknown
		//IL_003a: 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_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(1f, 0.5f, 0.8f, 1f);
		Color[] array = (Color[])(object)new Color[4096];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = val2;
		}
		val.SetPixels(array);
		val.Apply();
		((Texture)val).filterMode = (FilterMode)1;
		return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
	}
}
public class FullBellyManager : MonoBehaviour
{
	[CompilerGenerated]
	private sealed class <DecayCoroutine>d__36 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public CharacterAfflictions afflictions;

		public FullBellyManager <>4__this;

		private float <bloatedDecayInterval>5__1;

		private float <bloatedDecayAmount>5__2;

		private float <fullnessDecayInterval>5__3;

		private float <fullnessDecayAmount>5__4;

		private Character <character>5__5;

		private float <bloatedAmount>5__6;

		private float <newBloatedAmount>5__7;

		private float <baseRate>5__8;

		private float <relativeDecayAmount>5__9;

		private float <baseRate>5__10;

		private float <baseRate>5__11;

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

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

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

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

		private bool MoveNext()
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Expected O, but got Unknown
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if ((Object)(object)afflictions == (Object)null)
				{
					return false;
				}
				<bloatedDecayInterval>5__1 = FullBellyPlugin.syncedBloatedDecayInterval;
				<bloatedDecayAmount>5__2 = FullBellyPlugin.syncedBloatedDecayAmount;
				<fullnessDecayInterval>5__3 = FullBellyPlugin.syncedFullnessDecayInterval;
				<fullnessDecayAmount>5__4 = FullBellyPlugin.syncedFullnessDecayAmount;
				<character>5__5 = Character.localCharacter;
				break;
			case 1:
				<>1__state = -1;
				if (FullBellyPlugin.syncedEnableFarting && (Object)(object)<character>5__5 != (Object)null && Random.value < FullBellyPlugin.syncedDecayFartChance)
				{
					<>4__this.TryFart(<character>5__5);
				}
				<newBloatedAmount>5__7 = Mathf.Max(0f, <bloatedAmount>5__6 - <bloatedDecayAmount>5__2);
				<>4__this.foodConsumptionAmount = <>4__this.fullnessThreshold + <newBloatedAmount>5__7;
				<>4__this.UpdateBloatedStatus(afflictions);
				if (<newBloatedAmount>5__7 <= 0f && <>4__this.isLabeledBloated)
				{
					<>4__this.isLabeledBloated = false;
					<>4__this.SetBloatedStatusWithFallback(afflictions, 0f, <>4__this.logger);
					if (!<>4__this.isLabeledFull && (Object)(object)afflictions != (Object)null)
					{
						<baseRate>5__8 = ((<>4__this.cachedHungerRate > 0f) ? <>4__this.cachedHungerRate : (0.0005f * Ascents.hungerRateMultiplier));
						afflictions.hungerPerSecond = <baseRate>5__8;
					}
				}
				goto IL_03db;
			case 2:
				<>1__state = -1;
				goto IL_03db;
			case 3:
				{
					<>1__state = -1;
					<relativeDecayAmount>5__9 = <fullnessDecayAmount>5__4 * <>4__this.fullnessThreshold;
					<>4__this.foodConsumptionAmount = Mathf.Max(0f, <>4__this.foodConsumptionAmount - <relativeDecayAmount>5__9);
					if (<>4__this.foodConsumptionAmount <= 0f && <>4__this.isLabeledFull)
					{
						<>4__this.isLabeledFull = false;
						if (!<>4__this.isLabeledBloated && (Object)(object)afflictions != (Object)null)
						{
							<baseRate>5__10 = ((<>4__this.cachedHungerRate > 0f) ? <>4__this.cachedHungerRate : (0.0005f * Ascents.hungerRateMultiplier));
							afflictions.hungerPerSecond = <baseRate>5__10;
						}
					}
					goto IL_03db;
				}
				IL_03db:
				if (FullBellyPlugin.cfgShowPercentageDisplay.Value)
				{
					<>4__this.EnsurePercentageText();
					<>4__this.UpdatePercentageDisplay();
				}
				break;
			}
			if (<>4__this.foodConsumptionAmount > 0f && (Object)(object)afflictions != (Object)null)
			{
				if ((<>4__this.isLabeledFull || <>4__this.isLabeledBloated) && afflictions.hungerPerSecond > 0f)
				{
					afflictions.hungerPerSecond = 0f;
				}
				<bloatedAmount>5__6 = <>4__this.foodConsumptionAmount - <>4__this.fullnessThreshold;
				if (<bloatedAmount>5__6 > 0f && FullBellyPlugin.syncedEnableOvereating)
				{
					<>2__current = (object)new WaitForSeconds(<bloatedDecayInterval>5__1);
					<>1__state = 1;
					return true;
				}
				if (<bloatedAmount>5__6 > 0f && !FullBellyPlugin.syncedEnableOvereating)
				{
					<>4__this.foodConsumptionAmount = <>4__this.fullnessThreshold;
					<>4__this.UpdateBloatedStatus(afflictions);
					<>2__current = (object)new WaitForSeconds(<fullnessDecayInterval>5__3);
					<>1__state = 2;
					return true;
				}
				<>2__current = (object)new WaitForSeconds(<fullnessDecayInterval>5__3);
				<>1__state = 3;
				return true;
			}
			if (<>4__this.foodConsumptionAmount <= 0f && (Object)(object)afflictions != (Object)null)
			{
				<>4__this.foodConsumptionAmount = 0f;
				<>4__this.isLabeledFull = false;
				<>4__this.isLabeledBloated = false;
				<>4__this.SetBloatedStatusWithFallback(afflictions, 0f, <>4__this.logger);
				<baseRate>5__11 = ((<>4__this.cachedHungerRate > 0f) ? <>4__this.cachedHungerRate : (0.0005f * Ascents.hungerRateMultiplier));
				afflictions.hungerPerSecond = <baseRate>5__11;
			}
			<>4__this.decayCoroutine = null;
			return false;
		}

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

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

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

		private object <>2__current;

		public FullBellyManager <>4__this;

		private int <maxWaits>5__1;

		private int <waited>5__2;

		private FieldInfo <isRegisteredField>5__3;

		private FieldInfo <cachedPluginField>5__4;

		private BaseUnityPlugin <pluginInstance>5__5;

		private Exception <ex>5__6;

		private bool <isAlreadyRegistered>5__7;

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

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

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

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<isRegisteredField>5__3 = null;
			<cachedPluginField>5__4 = null;
			<pluginInstance>5__5 = null;
			<ex>5__6 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Invalid comparison between Unknown and I4
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Invalid comparison between Unknown and I4
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(10f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<maxWaits>5__1 = 50;
				<waited>5__2 = 0;
				goto IL_00a0;
			case 2:
				<>1__state = -1;
				<waited>5__2++;
				goto IL_00a0;
			case 3:
				<>1__state = -1;
				return false;
			case 4:
				{
					<>1__state = -1;
					return false;
				}
				IL_00a0:
				if ((Object)(object)Character.localCharacter == (Object)null && <waited>5__2 < <maxWaits>5__1)
				{
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 2;
					return true;
				}
				if ((Object)(object)Character.localCharacter == (Object)null)
				{
					<>4__this.logger.LogWarning((object)"[Full Belly] Character not found after scene change, skipping re-registration.");
					return false;
				}
				if ((int)BloatedAffliction.BloatedType != 7 && (int)BloatedAffliction.BloatedType > 0)
				{
					<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(BloatedAffliction.CreateBarAfflictionComponent(<>4__this.logger));
					<>1__state = 3;
					return true;
				}
				<>4__this.logger.LogInfo((object)"[Full Belly] BloatedType not properly set, attempting re-registration...");
				<isRegisteredField>5__3 = typeof(BloatedAffliction).GetField("isRegistered", BindingFlags.Static | BindingFlags.NonPublic);
				if (<isRegisteredField>5__3 != null)
				{
					<isRegisteredField>5__3.SetValue(null, false);
				}
				<cachedPluginField>5__4 = typeof(BloatedAffliction).GetField("cachedPluginInstance", BindingFlags.Static | BindingFlags.NonPublic);
				<pluginInstance>5__5 = null;
				if (<cachedPluginField>5__4 != null)
				{
					ref BaseUnityPlugin reference = ref <pluginInstance>5__5;
					object? value = <cachedPluginField>5__4.GetValue(null);
					reference = (BaseUnityPlugin)((value is BaseUnityPlugin) ? value : null);
					if (!((Object)(object)<pluginInstance>5__5 != (Object)null))
					{
					}
				}
				if ((Object)(object)<pluginInstance>5__5 == (Object)null)
				{
					<pluginInstance>5__5 = (BaseUnityPlugin)(object)Object.FindObjectsByType<FullBellyPlugin>((FindObjectsSortMode)0).FirstOrDefault();
				}
				if ((Object)(object)<pluginInstance>5__5 != (Object)null)
				{
					try
					{
						BloatedAffliction.CreateBloatedAffliction(<>4__this.logger, <pluginInstance>5__5);
					}
					catch (Exception ex)
					{
						<ex>5__6 = ex;
						<isAlreadyRegistered>5__7 = (<ex>5__6.InnerException?.Message?.Contains("already registered")).GetValueOrDefault() || (<ex>5__6.Message?.Contains("already registered") ?? false);
						if (<isAlreadyRegistered>5__7)
						{
							<>4__this.logger.LogInfo((object)"[Full Belly] Status was already registered (expected) - this is OK");
						}
						else
						{
							<>4__this.logger.LogWarning((object)("[Full Belly] Failed to re-register Bloated affliction after scene change: " + <ex>5__6.Message));
							<>4__this.logger.LogWarning((object)("[Full Belly] Stack trace: " + <ex>5__6.StackTrace));
						}
					}
				}
				else
				{
					<>4__this.logger.LogWarning((object)"[Full Belly] Could not find FullBellyPlugin instance for re-registration (tried cached and FindObjectsByType)");
				}
				<>2__current = ((MonoBehaviour)<>4__this).StartCoroutine(BloatedAffliction.CreateBarAfflictionComponent(<>4__this.logger));
				<>1__state = 4;
				return true;
			}
		}

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

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

	private static GameObject managerObject;

	internal static FullBellyManager instance;

	private ManualLogSource logger;

	private float hungerRestoreAccumulator;

	private float lastRestoreTime;

	internal float fullnessThreshold;

	internal bool isLabeledFull;

	internal bool isLabeledBloated;

	private float cachedHungerRate = -1f;

	private HashSet<string> ignoredItems = new HashSet<string>();

	internal float foodConsumptionAmount = 0f;

	private float bloatedAmountStored = 0f;

	private Coroutine decayCoroutine = null;

	private TextMeshProUGUI percentageText;

	private bool isEditMode = false;

	private readonly float[] moveSpeeds = new float[5] { 5f, 10f, 25f, 50f, 100f };

	private int currentSpeedIndex = 1;

	private bool editModeKeyPressedLastFrame = false;

	private float CurrentMoveSpeed => moveSpeeds[currentSpeedIndex];

	private void Update()
	{
		if (FullBellyPlugin.cfgShowPercentageDisplay.Value)
		{
			HandleUIEditControls();
		}
	}

	private void HandleUIEditControls()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		if (!Input.GetKey((KeyCode)306) && !Input.GetKey((KeyCode)305))
		{
			return;
		}
		KeyCode value = FullBellyPlugin.cfgUIEditModeKey.Value;
		bool key = Input.GetKey(value);
		if (key && !editModeKeyPressedLastFrame)
		{
			isEditMode = !isEditMode;
			if (isEditMode)
			{
				EnsurePercentageText();
				if ((Object)(object)percentageText != (Object)null)
				{
					UpdatePercentageDisplay();
				}
				ManualLogSource obj = logger;
				if (obj != null)
				{
					obj.LogInfo((object)$"[Full Belly] UI Edit Mode: ON (Move Speed: {CurrentMoveSpeed} px/s, Press Ctrl+{value} to save)");
				}
			}
			else
			{
				((BaseUnityPlugin)FullBellyPlugin.Instance).Config.Save();
				ManualLogSource obj2 = logger;
				if (obj2 != null)
				{
					obj2.LogInfo((object)"[Full Belly] UI Edit Mode: OFF (Position saved)");
				}
			}
		}
		editModeKeyPressedLastFrame = key;
		KeyCode value2 = FullBellyPlugin.cfgUISpeedCycleKey.Value;
		if (Input.GetKeyDown(value2))
		{
			currentSpeedIndex = (currentSpeedIndex + 1) % moveSpeeds.Length;
			ManualLogSource obj3 = logger;
			if (obj3 != null)
			{
				obj3.LogInfo((object)$"[Full Belly] Move Speed: {CurrentMoveSpeed} px/s");
			}
		}
		if (!isEditMode)
		{
			return;
		}
		float num = CurrentMoveSpeed * Time.deltaTime;
		bool flag = false;
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(FullBellyPlugin.cfgPercentageOffsetX.Value, FullBellyPlugin.cfgPercentageOffsetY.Value);
		if (Input.GetKey((KeyCode)276))
		{
			val.x -= num;
			flag = true;
		}
		if (Input.GetKey((KeyCode)275))
		{
			val.x += num;
			flag = true;
		}
		if (Input.GetKey((KeyCode)274))
		{
			val.y -= num;
			flag = true;
		}
		if (Input.GetKey((KeyCode)273))
		{
			val.y += num;
			flag = true;
		}
		if (flag)
		{
			FullBellyPlugin.cfgPercentageOffsetX.Value = val.x;
			FullBellyPlugin.cfgPercentageOffsetY.Value = val.y;
			EnsurePercentageText();
			if ((Object)(object)percentageText != (Object)null)
			{
				UpdatePercentagePosition();
				UpdatePercentageDisplay();
			}
		}
	}

	public static void Initialize(ManualLogSource log, float threshold, string ignoredItemsCSV)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		if ((Object)(object)managerObject != (Object)null)
		{
			Object.Destroy((Object)(object)managerObject);
		}
		managerObject = new GameObject("FullBellyManager");
		Object.DontDestroyOnLoad((Object)(object)managerObject);
		instance = managerObject.AddComponent<FullBellyManager>();
		instance.logger = log;
		instance.fullnessThreshold = threshold;
		instance.ignoredItems = new HashSet<string>(from s in ignoredItemsCSV.Split(new char[1] { ',' })
			select s.Trim() into s
			where !string.IsNullOrEmpty(s)
			select s, StringComparer.OrdinalIgnoreCase);
		SceneManager.activeSceneChanged += instance.OnSceneChanged;
	}

	public void UpdateSyncedThreshold(float newThreshold)
	{
		if (Mathf.Abs(fullnessThreshold - newThreshold) > 0.001f)
		{
			fullnessThreshold = newThreshold;
		}
	}

	public static void HandleDeathStateChange(bool isNowDead)
	{
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		if (!((Object)(object)localCharacter == (Object)null) && ((MonoBehaviourPun)localCharacter).photonView.IsMine)
		{
			if (isNowDead)
			{
				instance.logger.LogInfo((object)"[Full Belly] Player died - clearing fullness UI.");
				instance.ClearFullnessUI();
			}
			else
			{
				instance.logger.LogInfo((object)"[Full Belly] Player revived - resetting fullness.");
				instance.ResetFullBelly("Player revived");
			}
		}
	}

	private void ClearFullnessUI()
	{
		if (decayCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(decayCoroutine);
			decayCoroutine = null;
		}
		if ((Object)(object)percentageText != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)percentageText).gameObject);
			percentageText = null;
		}
		isLabeledFull = false;
		isLabeledBloated = false;
		bloatedAmountStored = 0f;
		hungerRestoreAccumulator = 0f;
		lastRestoreTime = 0f;
	}

	public static void HandleHungerRestore(string itemName, float value)
	{
		if ((Object)(object)instance == (Object)null || string.IsNullOrEmpty(itemName) || value <= 0f || !FullBellyPlugin.isHandshakeValid)
		{
			return;
		}
		Character localCharacter = Character.localCharacter;
		CharacterData val = localCharacter?.data;
		if ((Object)(object)val != (Object)null && val.dead)
		{
			instance.logger.LogInfo((object)"[Full Belly] Ignored hunger while dead.");
			return;
		}
		string text = itemName.Replace("(Clone)", string.Empty).Trim();
		if (text.Contains(":"))
		{
			text = text.Split(new char[1] { ':' }).Last();
		}
		if (instance.ignoredItems.Contains(text.ToLowerInvariant()))
		{
			instance.logger.LogInfo((object)("[Full Belly] Ignored hunger from '" + text + "'."));
			return;
		}
		instance.hungerRestoreAccumulator += value;
		instance.lastRestoreTime = Time.time;
		instance.foodConsumptionAmount += value;
		if (!FullBellyPlugin.syncedEnableOvereating && instance.foodConsumptionAmount > instance.fullnessThreshold)
		{
			instance.foodConsumptionAmount = instance.fullnessThreshold;
		}
		instance.logger.LogInfo((object)$"[Full Belly] Ate {text}, value: {value * 100f:0.00}%, Total consumption: {instance.foodConsumptionAmount * 100f:0.00}%");
		CharacterAfflictions val2 = localCharacter?.refs?.afflictions;
		if ((Object)(object)val2 == (Object)null)
		{
			return;
		}
		if (!instance.isLabeledFull && instance.foodConsumptionAmount >= instance.fullnessThreshold)
		{
			instance.ApplyFullLabel(val2);
		}
		float num = instance.foodConsumptionAmount - instance.fullnessThreshold;
		if (FullBellyPlugin.syncedEnableOvereating && !instance.isLabeledBloated && num > 0f)
		{
			instance.ApplyBloatedLabel(val2);
		}
		if (instance.isLabeledFull)
		{
			if (FullBellyPlugin.syncedEnableFarting && Random.value < FullBellyPlugin.syncedFartChance)
			{
				instance.TryFart(localCharacter);
			}
			if (FullBellyPlugin.syncedEnableOvereating && instance.isLabeledBloated && num > 0f)
			{
				instance.UpdateBloatedStatus(val2);
			}
		}
		if (instance.decayCoroutine != null)
		{
			((MonoBehaviour)instance).StopCoroutine(instance.decayCoroutine);
		}
		instance.decayCoroutine = ((MonoBehaviour)instance).StartCoroutine(instance.DecayCoroutine(val2));
		if (FullBellyPlugin.cfgShowPercentageDisplay.Value)
		{
			instance.EnsurePercentageText();
			instance.UpdatePercentageDisplay();
		}
	}

	private void OnSceneChanged(Scene oldScene, Scene newScene)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Invalid comparison between Unknown and I4
		ResetFullBelly("Scene changed");
		try
		{
			float num = 0.0005f * Ascents.hungerRateMultiplier;
			if (num > 0f)
			{
				cachedHungerRate = num;
			}
		}
		catch
		{
		}
		if ((int)BloatedAffliction.BloatedType != 7)
		{
			((MonoBehaviour)this).StartCoroutine(DelayedAfflictionReRegistration());
		}
	}

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

	internal void SetBloatedStatusWithFallback(CharacterAfflictions afflictions, float bloatedAmount, ManualLogSource logger = null)
	{
		Character val = ((afflictions != null) ? ((Component)afflictions).GetComponent<Character>() : null);
		if (!((Object)(object)val == (Object)null) && !((Object)(object)((MonoBehaviourPun)val).photonView == (Object)null) && ((MonoBehaviourPun)val).photonView.IsMine)
		{
			bloatedAmountStored = bloatedAmount;
			if (logger != null)
			{
				logger.LogDebug((object)$"[Full Belly] Stored Bloated amount separately: {bloatedAmount:0.000} (not in status array)");
			}
			UpdateBloatedBarAffliction();
		}
	}

	internal float GetBloatedAmount()
	{
		return bloatedAmountStored;
	}

	private void UpdateBloatedBarAffliction()
	{
		//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)
		try
		{
			StaminaBar val = Object.FindFirstObjectByType<StaminaBar>((FindObjectsInactive)0);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			BarAffliction[] componentsInChildren = ((Component)val).GetComponentsInChildren<BarAffliction>(true);
			if (componentsInChildren == null)
			{
				return;
			}
			BarAffliction[] array = componentsInChildren;
			foreach (BarAffliction val2 in array)
			{
				if (val2.afflictionType == BloatedAffliction.BloatedType)
				{
					break;
				}
			}
		}
		catch
		{
		}
	}

	public void ResetFullBelly(string reason)
	{
		if (decayCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(decayCoroutine);
			decayCoroutine = null;
		}
		if ((Object)(object)percentageText != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)percentageText).gameObject);
			percentageText = null;
		}
		foodConsumptionAmount = 0f;
		bloatedAmountStored = 0f;
		CharacterAfflictions val = Character.localCharacter?.refs?.afflictions;
		if ((Object)(object)val != (Object)null)
		{
			float hungerPerSecond = ((cachedHungerRate > 0f) ? cachedHungerRate : (0.0005f * Ascents.hungerRateMultiplier));
			val.hungerPerSecond = hungerPerSecond;
			SetBloatedStatusWithFallback(val, 0f, logger);
		}
		isLabeledFull = false;
		isLabeledBloated = false;
		hungerRestoreAccumulator = 0f;
		lastRestoreTime = 0f;
		ManualLogSource obj = logger;
		if (obj != null)
		{
			obj.LogInfo((object)("[Full Belly] Reset: " + reason));
		}
	}

	private void ApplyFullLabel(CharacterAfflictions afflictions)
	{
		if (!((Object)(object)afflictions == (Object)null))
		{
			if (cachedHungerRate <= 0f)
			{
				cachedHungerRate = ((afflictions.hungerPerSecond > 0f) ? afflictions.hungerPerSecond : (0.0005f * Ascents.hungerRateMultiplier));
			}
			isLabeledFull = true;
			afflictions.hungerPerSecond = 0f;
			logger.LogInfo((object)$"[Full Belly] Player labeled as FULL. Consumption: {foodConsumptionAmount * 100f:0.00}%, Threshold: {fullnessThreshold * 100f:0.00}%");
			if (FullBellyPlugin.cfgShowPercentageDisplay.Value)
			{
				EnsurePercentageText();
				UpdatePercentageDisplay();
			}
		}
	}

	private void ApplyBloatedLabel(CharacterAfflictions afflictions)
	{
		if (!((Object)(object)afflictions == (Object)null) && FullBellyPlugin.syncedEnableOvereating)
		{
			isLabeledBloated = true;
			afflictions.hungerPerSecond = 0f;
			float num = foodConsumptionAmount - fullnessThreshold;
			UpdateBloatedStatus(afflictions);
			logger.LogInfo((object)$"[Full Belly] Player labeled as BLOATED. Bloated amount: {num * 100f:0.00}%");
			if (FullBellyPlugin.cfgShowPercentageDisplay.Value)
			{
				EnsurePercentageText();
				UpdatePercentageDisplay();
			}
		}
	}

	internal void UpdateBloatedStatus(CharacterAfflictions afflictions)
	{
		if ((Object)(object)afflictions == (Object)null)
		{
			return;
		}
		if (!FullBellyPlugin.syncedEnableOvereating)
		{
			if (isLabeledBloated)
			{
				isLabeledBloated = false;
				SetBloatedStatusWithFallback(afflictions, 0f, logger);
				if (!isLabeledFull && (Object)(object)afflictions != (Object)null)
				{
					float hungerPerSecond = ((cachedHungerRate > 0f) ? cachedHungerRate : (0.0005f * Ascents.hungerRateMultiplier));
					afflictions.hungerPerSecond = hungerPerSecond;
				}
			}
			else
			{
				SetBloatedStatusWithFallback(afflictions, 0f, logger);
			}
		}
		else
		{
			float num = foodConsumptionAmount - fullnessThreshold;
			if (num > 0f)
			{
				SetBloatedStatusWithFallback(afflictions, num, logger);
			}
			else
			{
				SetBloatedStatusWithFallback(afflictions, 0f, logger);
			}
		}
	}

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

	private void TryFart(Character character)
	{
		//IL_002e: 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)
		//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_0069: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)character == (Object)null)
		{
			return;
		}
		logger.LogInfo((object)"[Full Belly] Fart triggered!");
		try
		{
			GameUtils.instance.SpawnResourceAtPositionNetworked("VFX_SporeExploExploEdibleSpawn", character.Center, (RpcTarget)1);
			GameUtils.instance.RPC_SpawnResourceAtPosition("VFX_SporeExploExploEdibleSpawn_NoKnockback", character.Center);
			float num = 100f;
			character.AddForceToBodyPart(character.GetBodypartRig((BodypartType)0), Vector3.zero, Vector3.up * num);
		}
		catch (Exception ex)
		{
			logger.LogWarning((object)("[Full Belly] Failed to trigger fart: " + ex.Message));
		}
	}

	private void EnsureCanvas()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		GameObject obj = GameObject.Find("FullBellyNotificationCanvas");
		Canvas val = ((obj != null) ? obj.GetComponent<Canvas>() : null);
		if ((Object)(object)val == (Object)null)
		{
			GameObject val2 = new GameObject("FullBellyNotificationCanvas");
			val = val2.AddComponent<Canvas>();
			val.renderMode = (RenderMode)0;
			val.sortingOrder = 999;
			CanvasScaler val3 = val2.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1920f, 1080f);
			val3.screenMatchMode = (ScreenMatchMode)0;
			val3.matchWidthOrHeight = 0.5f;
			val2.AddComponent<GraphicRaycaster>();
			Object.DontDestroyOnLoad((Object)(object)val2);
		}
	}

	private void EnsurePercentageText()
	{
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		if (!FullBellyPlugin.cfgShowPercentageDisplay.Value)
		{
			return;
		}
		EnsureCanvas();
		GameObject obj = GameObject.Find("FullBellyNotificationCanvas");
		Canvas val = ((obj != null) ? obj.GetComponent<Canvas>() : null);
		if ((Object)(object)val == (Object)null)
		{
			ManualLogSource obj2 = logger;
			if (obj2 != null)
			{
				obj2.LogWarning((object)"[Full Belly] Could not find FullBellyNotificationCanvas for percentage display.");
			}
			return;
		}
		if ((Object)(object)percentageText == (Object)null)
		{
			GameObject val2 = new GameObject("FullBellyPercentageText");
			val2.transform.SetParent(((Component)val).transform);
			val2.SetActive(true);
			percentageText = val2.AddComponent<TextMeshProUGUI>();
			((Graphic)percentageText).raycastTarget = false;
			((TMP_Text)percentageText).enableWordWrapping = false;
			((TMP_Text)percentageText).alignment = (TextAlignmentOptions)514;
			((TMP_Text)percentageText).fontStyle = (FontStyles)1;
			try
			{
				TextMeshProUGUI val3 = Object.FindFirstObjectByType<TextMeshProUGUI>();
				if ((Object)(object)val3 != (Object)null && (Object)(object)((TMP_Text)val3).font != (Object)null)
				{
					((TMP_Text)percentageText).font = ((TMP_Text)val3).font;
				}
			}
			catch
			{
			}
		}
		RectTransform component = ((Component)percentageText).GetComponent<RectTransform>();
		component.sizeDelta = new Vector2(800f, 100f);
		component.anchorMin = new Vector2(0.5f, 0.5f);
		component.anchorMax = new Vector2(0.5f, 0.5f);
		component.pivot = new Vector2(0.5f, 0.5f);
		UpdatePercentagePosition();
		((TMP_Text)percentageText).fontSize = Mathf.Clamp(FullBellyPlugin.cfgPercentageFontSize.Value, 10, 96);
		((Graphic)percentageText).color = ParseColor(FullBellyPlugin.cfgPercentageColor.Value, Color.white);
		if ((Object)(object)((Component)percentageText).gameObject != (Object)null)
		{
			((Component)percentageText).gameObject.SetActive(true);
		}
	}

	private void UpdatePercentageDisplay()
	{
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		if (!FullBellyPlugin.cfgShowPercentageDisplay.Value)
		{
			return;
		}
		if ((Object)(object)percentageText == (Object)null)
		{
			EnsurePercentageText();
			if ((Object)(object)percentageText == (Object)null)
			{
				ManualLogSource obj = logger;
				if (obj != null)
				{
					obj.LogWarning((object)"[Full Belly] Could not create percentage text component for display.");
				}
				return;
			}
		}
		if (foodConsumptionAmount <= 0f)
		{
			if (isEditMode)
			{
				((TMP_Text)percentageText).text = "100% Full\n100% Bloated";
				((Graphic)percentageText).color = ParseColor(FullBellyPlugin.cfgPercentageColor.Value, Color.white) * new Color(1f, 1f, 1f, 0.7f);
			}
			else
			{
				((TMP_Text)percentageText).text = "";
			}
			return;
		}
		if (!isEditMode)
		{
			((Graphic)percentageText).color = ParseColor(FullBellyPlugin.cfgPercentageColor.Value, Color.white);
		}
		float num = foodConsumptionAmount - fullnessThreshold;
		string text;
		if (foodConsumptionAmount < fullnessThreshold)
		{
			float num2 = foodConsumptionAmount / fullnessThreshold * 100f;
			text = $"{num2:0.0}% Full";
		}
		else if (num <= 0f || !FullBellyPlugin.syncedEnableOvereating)
		{
			text = "100% Full";
		}
		else if (FullBellyPlugin.isStaminaInfoForkedDetected)
		{
			text = "100% Full";
		}
		else
		{
			float num3 = num * 100f;
			text = $"100% Full\n{num3:0.0}% Bloated";
		}
		((TMP_Text)percentageText).text = text;
		((Graphic)percentageText).color = ParseColor(FullBellyPlugin.cfgPercentageColor.Value, Color.white);
	}

	private void UpdatePercentagePosition()
	{
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)percentageText == (Object)null)
		{
			return;
		}
		RectTransform component = ((Component)percentageText).GetComponent<RectTransform>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		Canvas canvas = ((Graphic)percentageText).canvas;
		if ((Object)(object)canvas == (Object)null)
		{
			return;
		}
		RectTransform component2 = ((Component)canvas).GetComponent<RectTransform>();
		if (!((Object)(object)component2 == (Object)null))
		{
			float num = component2.sizeDelta.y;
			if (num <= 0f)
			{
				num = Screen.height;
			}
			float num2 = (0f - num) / 3f;
			float value = FullBellyPlugin.cfgPercentageOffsetX.Value;
			float num3 = num2 + FullBellyPlugin.cfgPercentageOffsetY.Value;
			component.anchoredPosition = new Vector2(value, num3);
		}
	}

	private static Color ParseColor(string s, Color fallback)
	{
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (string.IsNullOrWhiteSpace(s))
			{
				return fallback;
			}
			s = s.Trim();
			if (s.StartsWith("#"))
			{
				string text = s.Substring(1);
				byte b = byte.MaxValue;
				byte b2 = byte.MaxValue;
				byte b3 = byte.MaxValue;
				byte b4 = byte.MaxValue;
				if (text.Length == 6 || text.Length == 8)
				{
					b = byte.Parse(text.Substring(0, 2), NumberStyles.HexNumber);
					b2 = byte.Parse(text.Substring(2, 2), NumberStyles.HexNumber);
					b3 = byte.Parse(text.Substring(4, 2), NumberStyles.HexNumber);
					if (text.Length == 8)
					{
						b4 = byte.Parse(text.Substring(6, 2), NumberStyles.HexNumber);
					}
					return Color32.op_Implicit(new Color32(b, b2, b3, b4));
				}
			}
		}
		catch
		{
		}
		return fallback;
	}
}
[HarmonyPatch(typeof(Item))]
public static class Patch_Item_Consume
{
	[HarmonyPostfix]
	[HarmonyPatch("Consume")]
	public static void Postfix(Item __instance, int consumerID)
	{
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Invalid comparison between Unknown and I4
		if ((Object)(object)__instance == (Object)null)
		{
			return;
		}
		PhotonView photonView = PhotonNetwork.GetPhotonView(consumerID);
		if ((Object)(object)photonView == (Object)null)
		{
			return;
		}
		Character component = ((Component)photonView).GetComponent<Character>();
		if ((Object)(object)component == (Object)null || !((MonoBehaviourPun)component).photonView.IsMine)
		{
			return;
		}
		float num = 0f;
		ItemActionBase[] components = ((Component)__instance).GetComponents<ItemActionBase>();
		ItemActionBase[] array = components;
		foreach (ItemActionBase val in array)
		{
			Action_RestoreHunger val2 = (Action_RestoreHunger)(object)((val is Action_RestoreHunger) ? val : null);
			if (val2 != null && val2.restorationAmount > 0f)
			{
				num += val2.restorationAmount;
				continue;
			}
			Action_ModifyStatus val3 = (Action_ModifyStatus)(object)((val is Action_ModifyStatus) ? val : null);
			if (val3 != null && (int)val3.statusType == 1 && val3.changeAmount < 0f)
			{
				num += 0f - val3.changeAmount;
			}
		}
		if (num > 0f)
		{
			FullBellyManager.HandleHungerRestore(((Object)__instance).name, num);
		}
	}
}
[HarmonyPatch(typeof(Character))]
public static class Patch_Character_Start
{
	[HarmonyPostfix]
	[HarmonyPatch("Start")]
	public static void Postfix(Character __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && ((MonoBehaviourPun)__instance).photonView.IsMine)
		{
			__instance.reviveAction = (Action)Delegate.Combine(__instance.reviveAction, (Action)delegate
			{
				FullBellyManager.HandleDeathStateChange(isNowDead: false);
			});
		}
	}
}
[HarmonyPatch(typeof(RunManager), "StartRun")]
public static class Patch_RunManager_StartRun
{
	public static void Postfix()
	{
		FullBellyPlugin instance = FullBellyPlugin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			Debug.LogError((object)"[Full Belly] Instance not found!");
			return;
		}
		instance.Logger.LogInfo((object)"[Full Belly] Run started - triggering config sync retry");
		if (instance.configSyncRetryCoroutine != null)
		{
			((MonoBehaviour)instance).StopCoroutine(instance.configSyncRetryCoroutine);
			instance.configSyncRetryCoroutine = null;
		}
		instance.configSyncRetryCoroutine = ((MonoBehaviour)instance).StartCoroutine(instance.RetryConfigSyncCoroutine());
	}
}
[HarmonyPatch(typeof(CharacterAfflictions))]
public static class Patch_CharacterAfflictions_PrettyPrint_Safety
{
	[HarmonyFinalizer]
	[HarmonyPatch("PrettyPrintStaminaBar")]
	public static Exception Finalizer_PrettyPrintStaminaBar(Exception __exception)
	{
		if (__exception is IndexOutOfRangeException)
		{
			FullBellyPlugin instance = FullBellyPlugin.Instance;
			if (instance != null)
			{
				instance.Logger.LogWarning((object)"[Full Belly] Suppressed IndexOutOfRangeException in PrettyPrintStaminaBar (likely from old cached ReconnectData - arrays are no longer extended)");
			}
			return null;
		}
		return __exception;
	}
}
[HarmonyPatch(typeof(CharacterAfflictions))]
public static class Patch_GetCurrentStatus_Bloated
{
	[HarmonyPostfix]
	[HarmonyPatch("GetCurrentStatus", new Type[] { typeof(STATUSTYPE) })]
	public static void Postfix_GetCurrentStatus(STATUSTYPE statusType, CharacterAfflictions __instance, ref float __result)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Invalid comparison between Unknown and I4
		//IL_003c: 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)
		try
		{
			if (!((Object)(object)__instance == (Object)null) && !((Object)(object)FullBellyManager.instance == (Object)null) && (int)BloatedAffliction.BloatedType != 7 && (int)BloatedAffliction.BloatedType != 0 && statusType == BloatedAffliction.BloatedType)
			{
				Character component = ((Component)__instance).GetComponent<Character>();
				if ((Object)(object)component != (Object)null && (Object)(object)((MonoBehaviourPun)component).photonView != (Object)null && ((MonoBehaviourPun)component).photonView.IsMine)
				{
					__result = FullBellyManager.instance.GetBloatedAmount();
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(CharacterAfflictions))]
public static class Patch_statusSum_IncludeBloated
{
	[HarmonyPostfix]
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	public static void Postfix_statusSum(CharacterAfflictions __instance, ref float __result)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Invalid comparison between Unknown and I4
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Invalid comparison between Unknown and I4
		try
		{
			Character val = ((__instance != null) ? ((Component)__instance).GetComponent<Character>() : null);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)((MonoBehaviourPun)val).photonView == (Object)null) && ((MonoBehaviourPun)val).photonView.IsMine && !((Object)(object)FullBellyManager.instance == (Object)null) && (int)BloatedAffliction.BloatedType != 7 && (int)BloatedAffliction.BloatedType != 0)
			{
				float bloatedAmount = FullBellyManager.instance.GetBloatedAmount();
				if (bloatedAmount > 0f)
				{
					__result += bloatedAmount;
				}
			}
		}
		catch
		{
		}
	}
}
[HarmonyPatch(typeof(CharacterAfflictions))]
public static class Patch_BlockHungerWhenLabeled
{
	[HarmonyPrefix]
	[HarmonyPatch("AddStatus", new Type[]
	{
		typeof(STATUSTYPE),
		typeof(float),
		typeof(bool),
		typeof(bool)
	})]
	public static bool Prefix(STATUSTYPE statusType, float amount, bool fromRPC, bool playEffects, CharacterAfflictions __instance)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		if ((int)statusType != 1 || amount <= 0f)
		{
			return true;
		}
		FullBellyManager instance = FullBellyManager.instance;
		if ((Object)(object)instance != (Object)null && (instance.isLabeledFull || instance.isLabeledBloated))
		{
			return false;
		}
		return true;
	}

	[HarmonyPrefix]
	[HarmonyPatch("AdjustStatus")]
	public static bool Prefix_AdjustStatus(STATUSTYPE statusType, float amount, CharacterAfflictions __instance)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		if ((int)statusType != 1 || amount <= 0f)
		{
			return true;
		}
		FullBellyManager instance = FullBellyManager.instance;
		if ((Object)(object)instance != (Object)null && (instance.isLabeledFull || instance.isLabeledBloated))
		{
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Character))]
public static class Patch_Character_RPCA_Die
{
	[HarmonyPostfix]
	[HarmonyPatch("RPCA_Die")]
	public static void Postfix(Character __instance)
	{
		if (!((Object)(object)__instance == (Object)null) && ((MonoBehaviourPun)__instance).photonView.IsMine && (Object)(object)FullBellyManager.instance != (Object)null)
		{
			FullBellyManager.HandleDeathStateChange(isNowDead: true);
		}
	}
}
[HarmonyPatch]
public static class Patch_PhotonCallbacks
{
	private static MethodBase TargetMethod_OnPlayerEnteredRoom()
	{
		Type type = Type.GetType("ReconnectHandler, Assembly-CSharp");
		if (type != null)
		{
			return type.GetMethod("OnPlayerEnteredRoom", BindingFlags.Instance | BindingFlags.Public);
		}
		return null;
	}

	[HarmonyPostfix]
	public static void Postfix_OnPlayerEnteredRoom(Player newPlayer)
	{
		FullBellyPlugin instance = FullBellyPlugin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		if (PhotonNetwork.IsMasterClient && PhotonNetwork.IsConnectedAndReady)
		{
			instance.Logger.LogInfo((object)("[Full Belly] Player " + (((newPlayer != null) ? newPlayer.UserId : null) ?? "unknown") + " entered room - sending config and handshake"));
			instance.AttemptConfigSync(forceSync: true);
		}
		else if (!PhotonNetwork.IsMasterClient && newPlayer != null)
		{
			string userId = newPlayer.UserId;
			Player localPlayer = PhotonNetwork.LocalPlayer;
			if (userId == ((localPlayer != null) ? localPlayer.UserId : null))
			{
				instance.Logger.LogInfo((object)"[Full Belly] Local player entered room - re-validating handshake");
				FullBellyPlugin.isHandshakeValid = false;
				instance.AttemptConfigSync(forceSync: true);
			}
		}
	}

	private static MethodBase TargetMethod_OnMasterClientSwitched()
	{
		Type type = Type.GetType("ReconnectHandler, Assembly-CSharp");
		if (type != null)
		{
			return type.GetMethod("OnMasterClientSwitched", BindingFlags.Instance | BindingFlags.Public);
		}
		return null;
	}

	[HarmonyPostfix]
	public static void Postfix_OnMasterClientSwitched(Player newMasterClient)
	{
		FullBellyPlugin instance = FullBellyPlugin.Instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		instance.Logger.LogInfo((object)("[Full Belly] Master client switched to " + (((newMasterClient != null) ? newMasterClient.UserId : null) ?? "unknown") + " - resetti