Decompiled source of SimpleStatsTweaked v0.6.97

SimpleStatsTweaked.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using BepInEx;
using Gunfiguration;
using HarmonyLib;
using ItemAPI;
using MonoMod.RuntimeDetour;
using SimpleStatsTweaked;
using UnityEngine;
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("Mod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mod")]
[assembly: AssemblyCopyright("Copyright ©  2020")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("57445610-0892-47c3-be16-453172104123")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SimpleStatsTweaked
{
	public static class KGUI
	{
		public static Font font;

		public static Transform KGUIRoot;

		public static Transform KGUIController;

		private static Canvas m_canvas;

		public static readonly Dictionary<TextAnchor, Vector2> AnchorMap = new Dictionary<TextAnchor, Vector2>
		{
			{
				(TextAnchor)6,
				new Vector2(0f, 0f)
			},
			{
				(TextAnchor)7,
				new Vector2(0.5f, 0f)
			},
			{
				(TextAnchor)8,
				new Vector2(1f, 0f)
			},
			{
				(TextAnchor)3,
				new Vector2(0f, 0.5f)
			},
			{
				(TextAnchor)4,
				new Vector2(0.5f, 0.5f)
			},
			{
				(TextAnchor)5,
				new Vector2(1f, 0.5f)
			},
			{
				(TextAnchor)0,
				new Vector2(0f, 1f)
			},
			{
				(TextAnchor)1,
				new Vector2(0.5f, 1f)
			},
			{
				(TextAnchor)2,
				new Vector2(1f, 1f)
			}
		};

		private static Color defaultTextColor = new Color(1f, 1f, 1f, 0.5f);

		public static bool Toggle(bool input)
		{
			bool result = !((Component)KGUIRoot).gameObject.activeSelf;
			((Component)KGUIRoot).gameObject.SetActive(input);
			return result;
		}

		public static void SetVisible(bool visible)
		{
			((Component)KGUIRoot).gameObject.SetActive(visible);
		}

		public static bool GetVisible()
		{
			return ((Component)KGUIRoot).gameObject.activeSelf;
		}

		public static void Init()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			KGUIController = new GameObject("KGUIController").transform;
			Object.DontDestroyOnLoad((Object)(object)((Component)KGUIController).gameObject);
			CreateCanvas();
			KGUIRoot = ((Component)m_canvas).transform;
			KGUIRoot.SetParent(KGUIController);
		}

		public static void CreateCanvas()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			GameObject val = new GameObject("Canvas");
			Object.DontDestroyOnLoad((Object)(object)val);
			m_canvas = val.AddComponent<Canvas>();
			m_canvas.renderMode = (RenderMode)0;
			m_canvas.sortingOrder = 100000;
			val.AddComponent<CanvasScaler>();
			val.AddComponent<GraphicRaycaster>();
		}

		public static Text CreateText(Transform parent, Vector2 offset, string text, TextAnchor anchor = 4, int font_size = 20)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Text");
			val.transform.SetParent(((Object)(object)parent != (Object)null) ? parent : KGUIRoot);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.SetTextAnchor(anchor);
			val2.anchoredPosition = offset;
			Tools.LogPropertiesAndFields<Font>(Tools.sharedAuto1.LoadAsset<Font>("04b_03__"));
			Text val3 = val.AddComponent<Text>();
			val3.horizontalOverflow = (HorizontalWrapMode)1;
			val3.verticalOverflow = (VerticalWrapMode)1;
			val3.alignment = anchor;
			val3.text = text;
			val3.font = Tools.sharedAuto1.LoadAsset<Font>("04b_03__");
			val3.fontSize = font_size;
			((Graphic)val3).color = defaultTextColor;
			return val3;
		}

		public static void SetTextAnchor(this RectTransform r, TextAnchor anchor)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			r.anchorMin = AnchorMap[anchor];
			r.anchorMax = AnchorMap[anchor];
			r.pivot = AnchorMap[anchor];
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("SimplyFenton.etg.simplestatstweaked", "SimpleStatsTweaked", "0.6.97")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "SimplyFenton.etg.simplestatstweaked";

		public const string NAME = "SimpleStatsTweaked";

		public const string VERSION = "0.6.97";

		public const string TEXT_COLOR = "#00FFFF";

		public void Start()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			ETGModMainBehaviour.WaitForGameManagerStart((Action<GameManager>)GMStart);
			new Hook((MethodBase)typeof(GameStatsManager).GetMethod("BeginNewSession", BindingFlags.Instance | BindingFlags.Public), typeof(Plugin).GetMethod("PreRunStart"));
		}

		public void GMStart(GameManager g)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			try
			{
				Tools.Init();
				KGUI.Init();
				((Component)KGUI.KGUIController).gameObject.AddComponent<SimpleStats>();
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
			Harmony val = new Harmony("SimplyFenton.etg.simplestatstweaked");
			val.PatchAll();
			Log("SimpleStatsTweaked v0.6.97 started successfully.", "#00FFFF");
		}

		public static void PreRunStart(Action<GameStatsManager, PlayerController> orig, GameStatsManager self, PlayerController player)
		{
			orig(self, player);
			SimpleStats.spiceCount = 0;
		}

		public static void SetStat(string[] args, PlayerController player)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Invalid comparison between Unknown and I4
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Invalid comparison between Unknown and I4
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			string statInput = ((args == null) ? string.Empty : args[0]);
			if (string.IsNullOrEmpty(statInput))
			{
				Tools.PrintError("Invalid stat ID: \"" + statInput + "\".");
				Tools.PrintError("Usage: setstat <stat> <number>");
				return;
			}
			if (args.Length == 1)
			{
				Tools.PrintError("No stat value found.");
				Tools.PrintError("Usage: setstat <stat> <number>");
				return;
			}
			string key = SimpleStats.StatMap.FirstOrDefault((KeyValuePair<string, string> x) => SimpleStats.FormatString(x.Value) == statInput).Key;
			StatType val = (StatType)2;
			try
			{
				val = Tools.GetEnumValue<StatType>(key, upper: false);
			}
			catch (Exception e)
			{
				Tools.PrintError("Invalid stat name: " + statInput);
				Tools.PrintException(e);
				return;
			}
			if (!float.TryParse(args[1], out var result))
			{
				Tools.PrintError("Invalid value: \"" + args[1] + "\"");
				Tools.PrintError("Usage: setstat <stat> 4<number>");
				return;
			}
			if ((int)val == 27)
			{
				player.rollStats.rollDistanceMultiplier = result;
			}
			else if ((int)val == 28)
			{
				player.rollStats.rollTimeMultiplier = result;
			}
			player.stats.SetBaseStatValue(val, result, player);
			Tools.Print($"{key} = {result}", "CCCCFF", force: true);
		}

		public static void HandleToggle2(string input, bool state)
		{
			foreach (string value in SimpleStats.StatMap.Values)
			{
				string text = SimpleStats.FormatString(value);
				if (SimpleStats.FormatString(input).Equals(text))
				{
					SimpleStats.Instance.Toggle2(text, state);
					return;
				}
			}
			SimpleStats.Instance.UpdateAppearance();
		}

		public static void HandleConditionalToggle2(string input, bool state = true)
		{
			foreach (string value in SimpleStats.StatMap.Values)
			{
				string text = SimpleStats.FormatString(value);
				if (SimpleStats.FormatString(input).Equals(text))
				{
					SimpleStats.Instance.ToggleConditional2(text, state);
					return;
				}
			}
			SimpleStats.Instance.UpdateAppearance();
		}

		public static void HandleKeybind(string Option)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			SimpleStats.keybind = (KeyCode)Enum.Parse(typeof(KeyCode), Option);
		}

		public static void HandleStatsToggle(bool state)
		{
			SimpleStats.Instance.ToggleVisibility(state);
		}

		public static void HandleFontSize(string input)
		{
			SimpleStats.fontSize = int.Parse(input);
			SimpleStats.Instance.UpdateAppearance();
		}

		public static void HandleBuffer(string input)
		{
			SimpleStats.buffer = int.Parse(input);
			SimpleStats.Instance.UpdateAppearance();
		}

		public static string[] AutoCompleteStatNames(string input)
		{
			List<string> list = new List<string>();
			foreach (string value in SimpleStats.StatMap.Values)
			{
				string text = SimpleStats.FormatString(value);
				if (StringAutocompletionExtensions.AutocompletionMatch(text, input.ToLower()))
				{
					list.Add(text.ToLower());
				}
			}
			return list.ToArray();
		}

		public static void Log(string text, string color = "FFFFFF")
		{
			ETGModConsole.Log((object)("<color=" + color + ">" + text + "</color>"), false);
		}

		public void Exit()
		{
		}

		public void Init()
		{
		}
	}
	public class SimpleStats : MonoBehaviour
	{
		public struct Configuration
		{
			public bool shown;

			public int fontSize;

			public int buffer;

			public string[] activeElements;

			public string[] conditionalElements;
		}

		public enum NewStatType
		{
			MovementSpeed,
			RateOfFire,
			Accuracy,
			Health,
			Coolness,
			Damage,
			ProjectileSpeed,
			AdditionalGunCapacity,
			AdditionalItemCapacity,
			AmmoCapacityMultiplier,
			ReloadSpeed,
			AdditionalShotPiercing,
			KnockbackMultiplier,
			GlobalPriceMultiplier,
			Curse,
			PlayerBulletScale,
			AdditionalClipCapacityMultiplier,
			AdditionalShotBounces,
			AdditionalBlanksPerFloor,
			ShadowBulletChance,
			ThrownGunDamage,
			DodgeRollDamage,
			DamageToBosses,
			EnemyProjectileSpeedMultiplier,
			ExtremeShadowBulletChance,
			ChargeAmountMultiplier,
			RangeMultiplier,
			DodgeRollDistanceMultiplier,
			DodgeRollSpeedMultiplier,
			TarnisherClipCapacityMultiplier,
			MoneyMultiplierFromEnemies,
			RatRing,
			SpiceCount,
			GunExplosionDamage
		}

		public static SimpleStats Instance;

		private bool m_built;

		private Dictionary<string, Text> textElements;

		private Dictionary<string, Text> textElements2;

		public static NewStatType[] stats = (NewStatType[])Enum.GetValues(typeof(NewStatType));

		private static Hook recalculateStats = new Hook((MethodBase)typeof(PlayerStats).GetMethod("RecalculateStatsInternal", BindingFlags.Instance | BindingFlags.Public), typeof(SimpleStats).GetMethod("OnUpdateStats"));

		private static Hook recalculateStats2 = new Hook((MethodBase)typeof(PassiveItem).GetMethod("DecrementFlag", BindingFlags.Static | BindingFlags.Public), typeof(SimpleStats).GetMethod("OnDecrementFlag", BindingFlags.Static | BindingFlags.Public));

		private static Hook onSpice = new Hook((MethodBase)typeof(SpiceItem).GetMethod("DoEffect", BindingFlags.Instance | BindingFlags.NonPublic), typeof(SimpleStats).GetMethod("OnSpice"));

		private static Hook postReload = new Hook((MethodBase)typeof(Gun).GetMethod("FinishReload", BindingFlags.Instance | BindingFlags.NonPublic), typeof(SimpleStats).GetMethod("PostReload"));

		private static Hook postAttack = new Hook((MethodBase)typeof(Gun).GetMethod("Attack", BindingFlags.Instance | BindingFlags.Public), typeof(SimpleStats).GetMethod("PostAttack"));

		private static string ConfigDirectory = Path.Combine(ETGMod.ResourcesDirectory, "sfconfig");

		private static string SaveFilePath = Path.Combine(ConfigDirectory, "simplestatstweaked.json");

		private static Hook activeReload = new Hook((MethodBase)typeof(Gun).GetMethod("OnActiveReloadSuccess", BindingFlags.Instance | BindingFlags.NonPublic), typeof(SimpleStats).GetMethod("OnActiveReload"));

		private static bool ActiveReloadSuccess = false;

		public static bool shown = true;

		public static int fontSize = 16;

		public static int buffer = 3;

		public static int spiceCount = 0;

		public static KeyCode keybind = (KeyCode)0;

		private static List<string> activeElements = new List<string>();

		private static List<string> conditionalElements = new List<string>();

		public static Dictionary<string, string> StatMap = new Dictionary<string, string>
		{
			{ "Accuracy", "Spread" },
			{ "AdditionalBlanksPerFloor", "Extra Per-Floor Blanks" },
			{ "AdditionalClipCapacityMultiplier", "Clip Size" },
			{ "AdditionalGunCapacity", "Gun Slots" },
			{ "AdditionalItemCapacity", "Extra Active Slots" },
			{ "AdditionalShotBounces", "Shot Bounces" },
			{ "AdditionalShotPiercing", "Shot Pierces" },
			{ "AmmoCapacityMultiplier", "Ammo Capacity" },
			{ "ChargeAmountMultiplier", "Charge Multiplier" },
			{ "Coolness", "Coolness" },
			{ "Curse", "Curse" },
			{ "Damage", "Damage" },
			{ "DamageToBosses", "Boss Damage" },
			{ "DodgeRollDamage", "Roll Damage" },
			{ "DodgeRollDistanceMultiplier", "Roll Distance" },
			{ "DodgeRollSpeedMultiplier", "Roll Time" },
			{ "EnemyProjectileSpeedMultiplier", "Enemy Shot Speed" },
			{ "ExtremeShadowBulletChance", "Y.V. Chance" },
			{ "GlobalPriceMultiplier", "Price Multiplier" },
			{ "GunExplosionDamage", "Gun Explosion Damage" },
			{ "Health", "Heart Containers" },
			{ "KnockbackMultiplier", "Knockback" },
			{ "MoneyMultiplierFromEnemies", "Money Drop Multiplier" },
			{ "MovementSpeed", "Speed" },
			{ "PlayerBulletScale", "Bullet Scale" },
			{ "ProjectileSpeed", "Shot Speed" },
			{ "RangeMultiplier", "Range" },
			{ "RateOfFire", "Rate of Fire" },
			{ "RatRing", "Rat Ring Rerolls" },
			{ "ReloadSpeed", "Reload Time" },
			{ "RoomDropChance", "Room Drop Chance" },
			{ "ShadowBulletChance", "Shadow Bullet Chance" },
			{ "SpiceCount", "Spice Counter" },
			{ "TarnisherClipCapacityMultiplier", "Tarnisher Clip Debuff" },
			{ "ThrownGunDamage", "Thrown Gun Damage" }
		};

		private void Start()
		{
			GameManager.Instance.OnNewLevelFullyLoaded += OnNewFloor;
			try
			{
				Build();
				Instance = this;
				UpdateAppearance();
			}
			catch (Exception e)
			{
				Tools.PrintException(e);
			}
			SimpleStatsTweakedConfig.Init();
			GameManager instance = GameManager.Instance;
			PlayerController val = ((instance != null) ? instance.PrimaryPlayer : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				KGUI.Toggle(input: false);
			}
		}

		private void Update()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown(keybind))
			{
				ToggleVisibility(!shown);
			}
		}

		public static void OnSpice(Action<SpiceItem, PlayerController> orig, SpiceItem spice, PlayerController player)
		{
			orig(spice, player);
			spiceCount++;
			Instance.UpdateAppearance();
		}

		private void Build()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			if (!m_built)
			{
				textElements = new Dictionary<string, Text>();
				textElements2 = new Dictionary<string, Text>();
				ETGModConsole.Log((object)"Building Stat Display...", false);
				float num = fontSize + buffer;
				float num2 = num * (float)stats.Length / 2f;
				for (int i = 0; i < stats.Length; i++)
				{
					textElements.Add(stats[i].ToString(), KGUI.CreateText(null, new Vector2(0f, (float)i * (0f - num) + num2), "", (TextAnchor)3, fontSize));
					textElements2.Add(stats[i].ToString(), KGUI.CreateText(null, new Vector2(60f, (float)i * (0f - num) + num2), "", (TextAnchor)5, fontSize));
				}
				KGUI.SetVisible(shown);
				m_built = true;
			}
		}

		public void ToggleVisibility(bool input)
		{
			bool flag = KGUI.Toggle(input);
			shown = input;
		}

		public void Toggle2(string statName, bool input)
		{
			string key = StatMap.FirstOrDefault((KeyValuePair<string, string> x) => FormatString(x.Value) == statName).Key;
			((Component)textElements[key]).gameObject.SetActive(input);
			((Component)textElements2[key]).gameObject.SetActive(input);
			if (input)
			{
				activeElements.Add(key);
			}
			else
			{
				activeElements.Remove(key);
			}
			RepositionElements();
		}

		public void ToggleConditional2(string statName, bool input)
		{
			string key = StatMap.FirstOrDefault((KeyValuePair<string, string> x) => FormatString(x.Value) == statName).Key;
			if (input)
			{
				conditionalElements.Add(key);
			}
			else
			{
				conditionalElements.Remove(key);
			}
			UpdateAppearance();
		}

		public void UpdateAppearance()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Invalid comparison between Unknown and I4
			if (!m_built)
			{
				return;
			}
			NewStatType[] array = stats;
			for (int i = 0; i < array.Length; i++)
			{
				NewStatType newStatType = array[i];
				string text = newStatType.ToString();
				Text val = Instance.textElements[text];
				val.text = StatMap[text] + ": " + FormatDecimal(GetStatValue(newStatType));
				val.fontSize = fontSize;
				((Component)val).gameObject.SetActive(activeElements.Contains(text) && ConditionalVisible(newStatType, 0));
				Text val2 = Instance.textElements2[text];
				if ((int)GameManager.Instance.CurrentGameType == 1)
				{
					val2.text = StatMap[text] + ": " + FormatDecimal(GetStatValue(newStatType, 1));
				}
				else
				{
					val2.text = string.Empty;
				}
				val2.fontSize = fontSize;
				((Component)val2).gameObject.SetActive(activeElements.Contains(text) && ConditionalVisible(newStatType, 1));
			}
			RepositionElements();
		}

		public bool ConditionalVisible(NewStatType playerStat, int playerID)
		{
			try
			{
				if (conditionalElements.Contains(playerStat.ToString()) && GetStatValue(playerStat, playerID) == (float)StatBaseValue(playerStat))
				{
					return false;
				}
				return true;
			}
			catch
			{
				return true;
			}
		}

		public int StatBaseValue(NewStatType stat)
		{
			return stat switch
			{
				NewStatType.Accuracy => 1, 
				NewStatType.AdditionalShotPiercing => 1, 
				NewStatType.ProjectileSpeed => 1, 
				NewStatType.ReloadSpeed => 1, 
				NewStatType.AmmoCapacityMultiplier => 1, 
				NewStatType.KnockbackMultiplier => 1, 
				NewStatType.GlobalPriceMultiplier => 1, 
				NewStatType.PlayerBulletScale => 1, 
				NewStatType.AdditionalClipCapacityMultiplier => 1, 
				NewStatType.ThrownGunDamage => 1, 
				NewStatType.DodgeRollDamage => 1, 
				NewStatType.DamageToBosses => 1, 
				NewStatType.EnemyProjectileSpeedMultiplier => 1, 
				NewStatType.ChargeAmountMultiplier => 1, 
				NewStatType.RangeMultiplier => 1, 
				NewStatType.DodgeRollDistanceMultiplier => 1, 
				NewStatType.DodgeRollSpeedMultiplier => 1, 
				NewStatType.TarnisherClipCapacityMultiplier => 1, 
				NewStatType.MoneyMultiplierFromEnemies => 1, 
				_ => 0, 
			};
		}

		public void RepositionElements()
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			List<RectTransform> list = new List<RectTransform>();
			List<RectTransform> list2 = new List<RectTransform>();
			List<string> list3 = new List<string>();
			foreach (KeyValuePair<string, Text> textElement in textElements)
			{
				if (((Component)textElement.Value).gameObject.activeSelf)
				{
					list.Add(((Component)textElement.Value).GetComponent<RectTransform>());
					list3.Add(textElement.Key);
				}
			}
			foreach (KeyValuePair<string, Text> item in textElements2)
			{
				if (((Component)item.Value).gameObject.activeSelf)
				{
					list2.Add(((Component)item.Value).GetComponent<RectTransform>());
				}
			}
			float num = fontSize + buffer;
			float num2 = num * (float)list.Count / 2f;
			for (int i = 0; i < list.Count; i++)
			{
				list[i].anchoredPosition = new Vector2(0f, (float)i * (0f - num) + num2);
			}
			for (int j = 0; j < list2.Count; j++)
			{
				list2[j].anchoredPosition = new Vector2(0f, (float)j * (0f - num) + num2);
			}
		}

		public static void OnUpdateStats(Action<PlayerStats, PlayerController> orig, PlayerStats self, PlayerController player)
		{
			orig(self, player);
			if (KGUI.GetVisible() != shown)
			{
				Instance.ToggleVisibility(shown);
			}
			if (Object.op_Implicit((Object)(object)Instance))
			{
				Instance.UpdateAppearance();
			}
		}

		public void OnNewFloor()
		{
			if (Object.op_Implicit((Object)(object)Instance))
			{
				Instance.UpdateAppearance();
			}
		}

		public static AttackResult PostAttack(Func<Gun, ProjectileData, GameObject, AttackResult> orig, Gun self, ProjectileData proj, GameObject obj)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			AttackResult result = orig(self, proj, obj);
			Instance.UpdateAppearance();
			return result;
		}

		public static void PostReload(Action<Gun, bool, bool, bool> orig, Gun self, bool bool1, bool bool2, bool bool3)
		{
			ActiveReloadSuccess = false;
			orig(self, bool1, bool2, bool3);
			Instance.UpdateAppearance();
		}

		public static void OnActiveReload(Action<Gun> orig, Gun self)
		{
			orig(self);
			ActiveReloadSuccess = true;
			Instance.UpdateAppearance();
		}

		public static void OnDecrementFlag(Action<PlayerController, Type> orig, PlayerController player, Type type)
		{
			orig(player, type);
			if (Object.op_Implicit((Object)(object)Instance))
			{
				Instance.UpdateAppearance();
			}
		}

		public float GetStatValue(NewStatType type, int playerID = 0)
		{
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			object obj;
			if (playerID != 0)
			{
				GameManager instance = GameManager.Instance;
				obj = ((instance != null) ? instance.SecondaryPlayer : null);
			}
			else
			{
				GameManager instance2 = GameManager.Instance;
				obj = ((instance2 != null) ? instance2.PrimaryPlayer : null);
			}
			PlayerController val = (PlayerController)obj;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return -1f;
			}
			switch (type)
			{
			case NewStatType.RatRing:
			{
				int num3 = 0;
				try
				{
					num3 = PassiveItem.ActiveFlagItems[val][typeof(RingOfResourcefulRatItem)];
				}
				catch
				{
				}
				return num3;
			}
			case NewStatType.Coolness:
			{
				float num2 = val.stats.GetStatValue((StatType)4);
				if (PassiveItem.IsFlagSetForCharacter(val, typeof(ChamberOfEvilItem)))
				{
					num2 += val.stats.GetStatValue((StatType)14) * 2f;
				}
				return num2;
			}
			case NewStatType.Damage:
				return GetDamage(val);
			case NewStatType.SpiceCount:
				return spiceCount;
			case NewStatType.GunExplosionDamage:
			{
				Gun val3 = ((val != null) ? ((GameActor)val).CurrentGun : null);
				if ((Object)(object)val3 == (Object)null)
				{
					return 0f;
				}
				ProjectileVolleyData volley = val3.Volley;
				ProjectileModule defaultModule = val3.DefaultModule;
				Projectile currentProjectile = defaultModule.GetCurrentProjectile();
				ProjectileData baseData = currentProjectile.baseData;
				ExplosiveModifier component = ((Component)currentProjectile).GetComponent<ExplosiveModifier>();
				return ((Object)(object)component != (Object)null) ? component.explosionData.damage : 0f;
			}
			case NewStatType.ShadowBulletChance:
			{
				List<float> list = new List<float>();
				foreach (PassiveItem passiveItem in val.passiveItems)
				{
					if ((object)((object)passiveItem).GetType() == typeof(ComplexProjectileModifier))
					{
						ComplexProjectileModifier val2 = (ComplexProjectileModifier)(object)((passiveItem is ComplexProjectileModifier) ? passiveItem : null);
						if (val2.UsesChanceForAdditionalProjectile && !val.HasActiveBonusSynergy((CustomSynergyType)12, false))
						{
							list.Add(val2.ActivationChance);
						}
					}
				}
				float num = 1f;
				foreach (float item in list)
				{
					num *= 1f - item;
				}
				return 1f - num;
			}
			default:
				return val.stats.GetStatValue(NewToOldEnum(type));
			}
		}

		public static float GetDamage(PlayerController player)
		{
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Invalid comparison between Unknown and I4
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Invalid comparison between Unknown and I4
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Invalid comparison between Unknown and I4
			List<Tuple<string, float>> list = new List<Tuple<string, float>>();
			if (player.passiveItems.Any())
			{
				foreach (PassiveItem passiveItem in player.passiveItems)
				{
					PassiveItem val = passiveItem;
					PassiveItem val2 = val;
					ScalingStatBoostItem val3 = (ScalingStatBoostItem)(object)((val2 is ScalingStatBoostItem) ? val2 : null);
					if (val3 == null)
					{
						ClipBulletModifierItem val4 = (ClipBulletModifierItem)(object)((val2 is ClipBulletModifierItem) ? val2 : null);
						if (val4 == null)
						{
							OurPowersCombinedItem val5 = (OurPowersCombinedItem)(object)((val2 is OurPowersCombinedItem) ? val2 : null);
							if (val5 == null)
							{
								CogOfBattleItem val6 = (CogOfBattleItem)(object)((val2 is CogOfBattleItem) ? val2 : null);
								if (val6 != null && Gun.ActiveReloadActivated && ActiveReloadSuccess)
								{
									list.Add(Tuple.Create<string, float>("MULTI", CogOfBattleItem.ACTIVE_RELOAD_DAMAGE_MULTIPLIER));
								}
							}
							else
							{
								list.Add(Tuple.Create<string, float>("FLAT", (float)typeof(OurPowersCombinedItem).InvokeMember("GetDamageContribution", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod, null, val5, null)));
							}
							continue;
						}
						float activationChance = val4.ActivationChance;
						if (activationChance == 1f && (int)((GameActor)player).CurrentGun.DefaultModule.shootStyle != 2)
						{
							if (val4.FirstShotBoost && ((GameActor)player).CurrentGun.ClipShotsRemaining == ((GameActor)player).CurrentGun.ClipCapacity)
							{
								list.Add(Tuple.Create<string, float>("MULTI", val4.FirstShotMultiplier));
							}
							if (val4.LastShotBoost && ((GameActor)player).CurrentGun.ClipShotsRemaining == 1)
							{
								list.Add(Tuple.Create<string, float>("MULTI", val4.LastShotMultiplier));
							}
						}
						continue;
					}
					float num = 0f;
					ScalingModeTarget scalingTarget = val3.ScalingTarget;
					ScalingModeTarget val7 = scalingTarget;
					if ((int)val7 != 0)
					{
						if ((int)val7 == 1)
						{
							num = Mathf.Clamp01(Mathf.InverseLerp(val3.ScalingTargetMin, val3.ScalingTargetMax, player.stats.GetStatValue((StatType)14)));
							num = val3.ScalingCurve.Evaluate(num);
						}
					}
					else
					{
						num = Mathf.Clamp01(Mathf.InverseLerp(val3.ScalingTargetMin, val3.ScalingTargetMax, (float)player.carriedConsumables.Currency));
						num = val3.ScalingCurve.Evaluate(num);
					}
					float num2 = Mathf.Lerp(val3.MinScaling, val3.MaxScaling, num);
					StatType targetStat = val3.TargetStat;
					if ((int)targetStat == 5)
					{
						list.Add(Tuple.Create<string, float>("MULTI", num2));
					}
				}
			}
			Gun val8 = ((player != null) ? ((GameActor)player).CurrentGun : null);
			if ((Object)(object)val8 == (Object)null)
			{
				return 0f;
			}
			ProjectileVolleyData volley = val8.Volley;
			ProjectileModule defaultModule = val8.DefaultModule;
			Projectile currentProjectile = defaultModule.GetCurrentProjectile();
			ProjectileData baseData = currentProjectile.baseData;
			float num3 = baseData.damage * player.stats.GetStatValue(NewToOldEnum(NewStatType.Damage));
			if (list.Count > 0)
			{
				foreach (Tuple<string, float> item in list)
				{
					string first = item.First;
					string text = first;
					if (!(text == "MULTI"))
					{
						if (text == "FLAT")
						{
							num3 += item.Second;
						}
					}
					else
					{
						num3 *= item.Second;
					}
				}
			}
			return num3;
		}

		public static string FormatDecimal(float num)
		{
			return num.ToString("F2").Replace(".00", "");
		}

		public static string FormatString(string s)
		{
			return s.ToLower().Replace(' ', '_');
		}

		public static StatType NewToOldEnum(NewStatType type)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (type == NewStatType.RatRing)
			{
				return (StatType)4;
			}
			return (StatType)Enum.Parse(typeof(StatType), type.ToString());
		}
	}
}
namespace ItemAPI
{
	public static class ResourceExtractor
	{
		private static string spritesDirectory = Path.Combine(ETGMod.ResourcesDirectory, "sprites");

		public static List<Texture2D> GetTexturesFromDirectory(string directoryPath)
		{
			if (!Directory.Exists(directoryPath))
			{
				Tools.PrintError(directoryPath + " not found.");
				return null;
			}
			List<Texture2D> list = new List<Texture2D>();
			string[] files = Directory.GetFiles(directoryPath);
			foreach (string text in files)
			{
				if (text.EndsWith(".png"))
				{
					Texture2D item = BytesToTexture(File.ReadAllBytes(text), Path.GetFileName(text).Replace(".png", ""));
					list.Add(item);
				}
			}
			return list;
		}

		public static Texture2D GetTextureFromFile(string fileName, string extension = ".png")
		{
			fileName = fileName.Replace(extension, "");
			string text = Path.Combine(spritesDirectory, fileName + extension);
			if (!File.Exists(text))
			{
				Tools.PrintError(text + " not found.");
				return null;
			}
			return BytesToTexture(File.ReadAllBytes(text), fileName);
		}

		public static List<string> GetCollectionFiles()
		{
			List<string> list = new List<string>();
			string[] files = Directory.GetFiles(spritesDirectory);
			foreach (string text in files)
			{
				if (text.EndsWith(".png"))
				{
					list.Add(Path.GetFileName(text).Replace(".png", ""));
				}
			}
			return list;
		}

		public static Texture2D BytesToTexture(byte[] bytes, string resourceName)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, bytes);
			((Texture)val).filterMode = (FilterMode)0;
			((Object)val).name = resourceName;
			return val;
		}

		public static string[] GetLinesFromEmbeddedResource(string filePath)
		{
			string text = BytesToString(ExtractEmbeddedResource(filePath));
			return text.Split(new char[1] { '\n' });
		}

		public static string[] GetLinesFromFile(string filePath)
		{
			string text = BytesToString(File.ReadAllBytes(filePath));
			return text.Split(new char[1] { '\n' });
		}

		public static string BytesToString(byte[] bytes)
		{
			return Encoding.UTF8.GetString(bytes, 0, bytes.Length);
		}

		public static List<string> GetResourceFolders()
		{
			List<string> list = new List<string>();
			string path = Path.Combine(ETGMod.ResourcesDirectory, "sprites");
			if (Directory.Exists(path))
			{
				string[] directories = Directory.GetDirectories(path);
				foreach (string path2 in directories)
				{
					list.Add(Path.GetFileName(path2));
				}
			}
			return list;
		}

		public static byte[] ExtractEmbeddedResource(string filePath)
		{
			filePath = filePath.Replace("/", ".");
			filePath = filePath.Replace("\\", ".");
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			using Stream stream = callingAssembly.GetManifestResourceStream(filePath);
			if (stream == null)
			{
				return null;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			return array;
		}

		public static Texture2D GetTextureFromResource(string resourceName)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			byte[] array = ExtractEmbeddedResource(resourceName);
			if (array == null)
			{
				Tools.PrintError("No bytes found in " + resourceName);
				return null;
			}
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			ImageConversion.LoadImage(val, array);
			((Texture)val).filterMode = (FilterMode)0;
			string text = resourceName.Substring(0, resourceName.LastIndexOf('.'));
			if (text.LastIndexOf('.') >= 0)
			{
				text = text.Substring(text.LastIndexOf('.') + 1);
			}
			((Object)val).name = text;
			return val;
		}

		public static string[] GetResourceNames()
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string[] manifestResourceNames = callingAssembly.GetManifestResourceNames();
			if (manifestResourceNames == null)
			{
				ETGModConsole.Log((object)"No manifest resources found.", false);
				return null;
			}
			return manifestResourceNames;
		}
	}
	public static class Tools
	{
		public static bool verbose = false;

		private static string defaultLog = Path.Combine(ETGMod.ResourcesDirectory, "simplestats.txt");

		public static AssetBundle sharedAuto1 = ResourceManager.LoadAssetBundle("shared_auto_001");

		public static AssetBundle sharedAuto2 = ResourceManager.LoadAssetBundle("shared_auto_002");

		public static string modID = "SS";

		public static void Init()
		{
			if (File.Exists(defaultLog))
			{
				File.Delete(defaultLog);
			}
		}

		public static void Print<T>(T obj, string color = "FFFFFF", bool force = false)
		{
			if (verbose || force)
			{
				ETGModConsole.Log((object)("<color=#" + color + ">[" + modID + "] " + obj.ToString() + "</color>"), false);
			}
			Log(obj.ToString());
		}

		public static void PrintRaw<T>(T obj, bool force = false)
		{
			if (verbose || force)
			{
				ETGModConsole.Log((object)obj.ToString(), false);
			}
			Log(obj.ToString());
		}

		public static void PrintError<T>(T obj, string color = "FF0000")
		{
			ETGModConsole.Log((object)("<color=#" + color + ">[" + modID + "] " + obj.ToString() + "</color>"), false);
			Log(obj.ToString());
		}

		public static void PrintException(Exception e, string color = "FF0000")
		{
			ETGModConsole.Log((object)("<color=#" + color + ">[" + modID + "] " + e.Message + "</color>"), false);
			ETGModConsole.Log((object)e.StackTrace, false);
			Log(e.Message);
			Log("\t" + e.StackTrace);
		}

		public static void Log<T>(T obj)
		{
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, defaultLog), append: true);
			streamWriter.WriteLine(obj.ToString());
		}

		public static void Log<T>(T obj, string fileName)
		{
			if (!verbose)
			{
				return;
			}
			using StreamWriter streamWriter = new StreamWriter(Path.Combine(ETGMod.ResourcesDirectory, fileName), append: true);
			streamWriter.WriteLine(obj.ToString());
		}

		public static void Dissect(this GameObject obj)
		{
			Print(((Object)obj).name + " Components:");
			Component[] components = obj.GetComponents<Component>();
			foreach (Component val in components)
			{
				Print("    " + ((object)val).GetType());
			}
		}

		public static void ShowHitBox(this SpeculativeRigidbody body)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			PixelCollider hitboxPixelCollider = body.HitboxPixelCollider;
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val).name = "HitboxDisplay";
			val.transform.SetParent(((BraveBehaviour)body).transform);
			Print(((Object)body).name ?? "");
			Print($"    Offset: {hitboxPixelCollider.Offset}, Dimesions: {hitboxPixelCollider.Dimensions}");
			val.transform.localScale = new Vector3((float)hitboxPixelCollider.Dimensions.x / 16f, (float)hitboxPixelCollider.Dimensions.y / 16f, 1f);
			Vector3 localPosition = new Vector3((float)hitboxPixelCollider.Offset.x + (float)hitboxPixelCollider.Dimensions.x * 0.5f, (float)hitboxPixelCollider.Offset.y + (float)hitboxPixelCollider.Dimensions.y * 0.5f, -16f) / 16f;
			val.transform.localPosition = localPosition;
		}

		public static void HideHitBox(this SpeculativeRigidbody body)
		{
			Transform val = ((BraveBehaviour)body).transform.Find("HitboxDisplay");
			if (Object.op_Implicit((Object)(object)val))
			{
				Object.Destroy((Object)(object)val);
			}
		}

		public static void ExportTexture(Texture texture)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			File.WriteAllBytes(Path.Combine(ETGMod.ResourcesDirectory, ((Object)texture).name + ".png"), ImageConversion.EncodeToPNG((Texture2D)texture));
		}

		public static T GetEnumValue<T>(string val, bool upper = true) where T : Enum
		{
			if (upper)
			{
				val = val.ToUpper();
			}
			return (T)Enum.Parse(typeof(T), val);
		}

		public static void LogPropertiesAndFields<T>(T obj, string header = "")
		{
			Log(header);
			Log("=======================");
			if (obj == null)
			{
				Log("LogPropertiesAndFields: Null object");
				return;
			}
			Type type = obj.GetType();
			Log($"Type: {type}");
			PropertyInfo[] properties = type.GetProperties();
			Log($"{typeof(T)} Properties: ");
			PropertyInfo[] array = properties;
			foreach (PropertyInfo propertyInfo in array)
			{
				try
				{
					object value = propertyInfo.GetValue(obj, null);
					string text = value.ToString();
					if ((object)obj?.GetType().GetGenericTypeDefinition() == typeof(List<>))
					{
						List<object> list = value as List<object>;
						text = $"List[{list.Count}]";
						foreach (object item in list)
						{
							text = text + "\n\t\t" + item.ToString();
						}
					}
					Log("\t" + propertyInfo.Name + ": " + text);
				}
				catch
				{
				}
			}
			Log($"{typeof(T)} Fields: ");
			FieldInfo[] fields = type.GetFields();
			FieldInfo[] array2 = fields;
			foreach (FieldInfo fieldInfo in array2)
			{
				Log($"\t{fieldInfo.Name}: {fieldInfo.GetValue(obj)}");
			}
		}
	}
}
namespace Gunfiguration
{
	public static class SimpleStatsTweakedConfig
	{
		internal static Gunfig _Gunfig;

		internal static void Init()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_Gunfig = Gunfig.Get(GunfigHelpers.WithColor("Simple Stats Tweaked", Color.white));
			Plugin.HandleStatsToggle(_Gunfig.Enabled("SimpleStatsTweaked Visible"));
			_Gunfig.AddToggle("SimpleStatsTweaked Visible", false, (string)null, (Action<string, string>)delegate(string optionKey, string optionValue)
			{
				Plugin.HandleStatsToggle((optionValue == "1") ? true : false);
			}, (Update)0);
			Plugin.HandleFontSize(_Gunfig.Value("Font Size") ?? "10");
			_Gunfig.AddScrollBox("Font Size", new List<string>
			{
				"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
				"11", "12", "13", "14", "15", "16", "17", "18", "19", "20"
			}, (string)null, (Action<string, string>)delegate(string optionKey, string optionValue)
			{
				Plugin.HandleFontSize(optionValue);
			}, (List<string>)null, (Update)0);
			Plugin.HandleBuffer(_Gunfig.Value("Buffer") ?? "3");
			_Gunfig.AddScrollBox("Buffer", new List<string>
			{
				"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
				"11", "12", "13", "14", "15", "16", "17", "18", "19", "20"
			}, (string)null, (Action<string, string>)delegate(string optionKey, string optionValue)
			{
				Plugin.HandleBuffer(optionValue);
			}, (List<string>)null, (Update)0);
			Plugin.HandleKeybind(_Gunfig.Value("Toggle Display Keybind") ?? "T");
			_Gunfig.AddScrollBox("Toggle Display Keybind", (from KeyCode v in Enum.GetValues(typeof(KeyCode))
				select ((object)(KeyCode)(ref v)).ToString()).ToList(), (string)null, (Action<string, string>)delegate(string optonKey, string optionValue)
			{
				Plugin.HandleKeybind(optionValue);
			}, (List<string>)null, (Update)0);
			_Gunfig.AddLabel("Toggle To Enable Or Disable Stats");
			_Gunfig.AddLabel("Toggle The Conditional Options");
			_Gunfig.AddLabel("To Enable Conditional Displaying");
			_Gunfig.AddLabel("Conditionals Will Only Display");
			_Gunfig.AddLabel("If Display Is Enabled And");
			_Gunfig.AddLabel("If Different From Their Base Value");
			List<string> list = SimpleStats.StatMap.Values.ToList();
			list.Sort();
			foreach (string item in list)
			{
				_Gunfig.AddLabel("");
				Plugin.HandleToggle2(item, _Gunfig.Enabled("Display: " + item));
				_Gunfig.AddToggle("Display: " + item, false, (string)null, (Action<string, string>)delegate(string optionKey, string optionValue)
				{
					Plugin.HandleToggle2(item, (optionValue == "1") ? true : false);
				}, (Update)0);
				Plugin.HandleConditionalToggle2(item, _Gunfig.Enabled("Conditional: " + item));
				_Gunfig.AddToggle("Conditional: " + item, false, (string)null, (Action<string, string>)delegate(string optionKey, string optionValue)
				{
					Plugin.HandleConditionalToggle2(item, (optionValue == "1") ? true : false);
				}, (Update)0);
			}
		}
	}
}