Decompiled source of LevelCaps v1.0.1

LevelCaps.dll

Decompiled 9 hours ago
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using GameImprovement.Ui;
using HarmonyLib;
using RoR2;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace LevelCaps
{
	[BepInPlugin("com.proigryfedorov.levelcaps", "LevelCaps", "1.0.1")]
	public class LevelCapsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.proigryfedorov.levelcaps";

		public const string PluginName = "LevelCaps";

		public const string PluginVersion = "1.0.1";

		internal static ConfigEntry<int> EnemyLevelCap;

		internal static ConfigEntry<float> PlayerCapRatio;

		internal static ConfigEntry<int> VanillaCurveUntil;

		internal static ConfigEntry<float> LevelCostGrowth;

		internal static ConfigEntry<bool> AdminMode;

		private static ulong playerExpCap = ulong.MaxValue;

		private static ulong[] experienceTable;

		private static uint monsterLevelLock;

		public static int EnemyCap => Math.Max(2, EnemyLevelCap.Value);

		public static int PlayerCap => Math.Max(1, Math.Min(EnemyCap, (int)Math.Round((float)EnemyCap * PlayerCapRatio.Value)));

		internal static bool MonsterLevelLocked => monsterLevelLock != 0;

		private void Awake()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected I4, but got Unknown
			EnemyLevelCap = ((BaseUnityPlugin)this).Config.Bind<int>("Levels", "EnemyLevelCap", 99999, "Максимальный уровень врагов (в игре 99).");
			PlayerCapRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Levels", "PlayerCapRatio", 0.5f, "Максимальный уровень игроков = максимальный уровень врагов × это число. 0.5 — в 2 раза меньше (99999 → 50000).");
			VanillaCurveUntil = ((BaseUnityPlugin)this).Config.Bind<int>("Experience", "VanillaCurveUntil", 30, "До этого уровня опыт для игроков считается как в игре (каждый уровень в 1,55 раза дороже предыдущего).");
			LevelCostGrowth = ((BaseUnityPlugin)this).Config.Bind<float>("Experience", "LevelCostGrowth", 1.03f, "Выше VanillaCurveUntil каждый уровень дороже предыдущего во столько раз. В игре 1.55 — с ним высокие уровни недостижимы.");
			AdminMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Admin", "AdminMode", false, "Админ-режим для тестов (только хост): в меню паузы появляется кнопка «Админ: уровни», где можно поставить уровень игроков и врагов. Сам выключается при запуске игры и в конце забега.");
			AdminMode.Value = false;
			Harmony val = new Harmony("com.proigryfedorov.levelcaps");
			val.Patch((MethodBase)AccessTools.Method(typeof(PauseScreenController), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(LevelCapsPlugin), "PauseAwakePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			try
			{
				Apply(val);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Не удалось поменять лимиты уровней: " + ex));
			}
			try
			{
				Apocalypse.Init(((BaseUnityPlugin)this).Config, val);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Сложность «Апокалипсис» добавлена (индекс " + (int)Apocalypse.Index + ")"));
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Не удалось добавить сложность «Апокалипсис»: " + ex2));
			}
			Run.onRunDestroyGlobal += delegate
			{
				monsterLevelLock = 0u;
				AdminMode.Value = false;
			};
		}

		private void Apply(Harmony harmony)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			int enemyCap = EnemyCap;
			int playerCap = PlayerCap;
			ulong[] array = BuildTable(enemyCap);
			RuntimeHelpers.RunClassConstructor(typeof(TeamManager).TypeHandle);
			RuntimeHelpers.RunClassConstructor(typeof(Run).TypeHandle);
			SetStatic(typeof(TeamManager), "levelToExperienceTable", array);
			SetStatic(typeof(TeamManager), "naturalLevelCap", (uint)enemyCap);
			SetStatic(typeof(TeamManager), "hardExpCap", array[^1]);
			SetStatic(typeof(Run), "ambientLevelCap", enemyCap);
			playerExpCap = array[playerCap];
			experienceTable = array;
			harmony.Patch((MethodBase)AccessTools.Method(typeof(TeamManager), "SetTeamExperience", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LevelCapsPlugin), "SetTeamExperiencePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("LevelCaps 1.0.1: враги до " + enemyCap + " уровня, игроки до " + playerCap + " (проверка: naturalLevelCap = " + TeamManager.naturalLevelCap + ")"));
		}

		private static ulong[] BuildTable(int cap)
		{
			ulong[] array = new ulong[cap + 1];
			int num = Math.Max(2, Math.Min(cap, VanillaCurveUntil.Value));
			double num2 = Math.Max(1.0001, LevelCostGrowth.Value);
			for (int i = 2; i <= num; i++)
			{
				array[i] = (ulong)(20.0 * (Math.Pow(1.55, i - 1) - 1.0) / 0.55);
			}
			double num3 = array[num] - array[num - 1];
			for (int j = num + 1; j <= cap; j++)
			{
				num3 *= num2;
				ulong num4 = array[j - 1];
				ulong num5 = ulong.MaxValue - num4;
				ulong num6 = (ulong)(cap - j + 1);
				ulong num7 = num5 / num6;
				ulong val = ((num3 >= (double)num7) ? num7 : ((ulong)num3));
				array[j] = num4 + Math.Max(1uL, val);
			}
			return array;
		}

		private static void SetStatic(Type type, string name, object value)
		{
			FieldInfo fieldInfo = AccessTools.Field(type, name);
			if (fieldInfo == null)
			{
				throw new MissingFieldException(type.Name, name);
			}
			fieldInfo.SetValue(null, value);
		}

		private static void SetTeamExperiencePrefix(TeamIndex teamIndex, ref ulong newExperience)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			if ((int)teamIndex == 1 && newExperience > playerExpCap)
			{
				newExperience = playerExpCap;
			}
			if ((int)teamIndex == 2 && monsterLevelLock != 0 && experienceTable != null)
			{
				newExperience = experienceTable[Math.Min(monsterLevelLock, (uint)(experienceTable.Length - 1))];
			}
		}

		private static void PauseAwakePostfix(PauseScreenController __instance)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			if (!AdminMode.Value || !NetworkServer.active || (Object)(object)Run.instance == (Object)null)
			{
				return;
			}
			try
			{
				RoR2Ui.AddPauseButton(__instance, "LevelCapsAdminButton", "Админ: уровни", (UnityAction)delegate
				{
					AdminMenu.Open(__instance);
				});
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[LevelCaps] Не удалось добавить кнопку в меню паузы: " + ex));
			}
		}

		internal static void SetPlayerLevel(uint level)
		{
			TeamManager.instance.SetTeamLevel((TeamIndex)1, level);
		}

		internal static void LockMonsterLevel(uint level)
		{
			monsterLevelLock = level;
			TeamManager.instance.SetTeamLevel((TeamIndex)2, level);
		}

		internal static void UnlockMonsterLevel()
		{
			monsterLevelLock = 0u;
		}
	}
	internal class AdminMenu : MonoBehaviour
	{
		private Submenu menu;

		private TextMeshProUGUI playerNow;

		private TextMeshProUGUI monsterNow;

		private TextMeshProUGUI status;

		private TMP_InputField playerInput;

		private TMP_InputField monsterInput;

		private GameObject unlockButton;

		public static void Open(PauseScreenController pause)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Submenu submenu = RoR2Ui.OpenSubmenu(pause, "LevelCapsAdmin", new Vector2(0.25f, 0.2f), new Vector2(0.75f, 0.8f));
			AdminMenu adminMenu = submenu.root.AddComponent<AdminMenu>();
			adminMenu.menu = submenu;
			adminMenu.Build();
		}

		private void Build()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Expected O, but got Unknown
			menu.Title("Админ-режим: уровни");
			menu.Text((Transform)(object)menu.box, "Лимиты: враги " + LevelCapsPlugin.EnemyCap + ", игроки " + LevelCapsPlugin.PlayerCap + (Apocalypse.Active ? "   ·   сложность «Апокалипсис»" : ""), 18f, (TextAlignmentOptions)514, RoR2Ui.MutedText);
			playerNow = menu.Text((Transform)(object)menu.box, "", 24f, (TextAlignmentOptions)1025, RoR2Ui.HeaderText);
			RoR2Ui.Size(((Component)playerNow).gameObject, 40f, -1f);
			RectTransform parent = menu.Row((Transform)(object)menu.box, 46f);
			playerInput = menu.Input((Transform)(object)parent, "100", 200f, null);
			menu.Button((Transform)(object)parent, "Поставить игрокам", (UnityAction)delegate
			{
				if (TryLevel(playerInput.text, (uint)LevelCapsPlugin.PlayerCap, out var level))
				{
					LevelCapsPlugin.SetPlayerLevel(level);
					((TMP_Text)status).text = "Игроки: уровень " + TeamManager.instance.GetTeamLevel((TeamIndex)1);
				}
			});
			monsterNow = menu.Text((Transform)(object)menu.box, "", 24f, (TextAlignmentOptions)1025, RoR2Ui.HeaderText);
			RoR2Ui.Size(((Component)monsterNow).gameObject, 40f, -1f);
			RectTransform parent2 = menu.Row((Transform)(object)menu.box, 46f);
			monsterInput = menu.Input((Transform)(object)parent2, "1000", 200f, null);
			menu.Button((Transform)(object)parent2, "Поставить и зафиксировать", (UnityAction)delegate
			{
				if (TryLevel(monsterInput.text, (uint)LevelCapsPlugin.EnemyCap, out var level))
				{
					LevelCapsPlugin.LockMonsterLevel(level);
					((TMP_Text)status).text = "Враги: уровень " + TeamManager.instance.GetTeamLevel((TeamIndex)2) + ", зафиксирован";
				}
			});
			RectTransform parent3 = menu.Row((Transform)(object)menu.box, 46f);
			unlockButton = menu.Button((Transform)(object)parent3, "Снять фиксацию (уровень врагов снова растёт со временем)", (UnityAction)delegate
			{
				LevelCapsPlugin.UnlockMonsterLevel();
				((TMP_Text)status).text = "Фиксация снята";
			});
			status = menu.Text((Transform)(object)menu.box, "", 18f, (TextAlignmentOptions)514, Color.white);
			RoR2Ui.Size(((Component)status).gameObject, 30f, -1f);
			((Component)RoR2Ui.NewRect("Spacer", (Transform)(object)menu.box)).gameObject.AddComponent<LayoutElement>().flexibleHeight = 1f;
			RectTransform parent4 = menu.Row((Transform)(object)menu.box, 46f);
			menu.Button((Transform)(object)parent4, "Назад", (UnityAction)delegate
			{
				menu.Close();
			});
		}

		private void Update()
		{
			if (!((Object)(object)TeamManager.instance == (Object)null))
			{
				((TMP_Text)playerNow).text = "Уровень игроков сейчас: " + TeamManager.instance.GetTeamLevel((TeamIndex)1);
				((TMP_Text)monsterNow).text = "Уровень врагов сейчас: " + TeamManager.instance.GetTeamLevel((TeamIndex)2) + (LevelCapsPlugin.MonsterLevelLocked ? "  (зафиксирован)" : "");
				unlockButton.SetActive(LevelCapsPlugin.MonsterLevelLocked);
			}
		}

		private bool TryLevel(string text, uint cap, out uint level)
		{
			if (!uint.TryParse((text ?? "").Trim(), out level) || level < 1)
			{
				((TMP_Text)status).text = "Введите число от 1 до " + cap;
				return false;
			}
			if (level > cap)
			{
				level = cap;
			}
			return true;
		}
	}
	internal static class Apocalypse
	{
		public const string NameToken = "LEVELCAPS_DIFFICULTY_APOCALYPSE_NAME";

		public const string DescriptionToken = "LEVELCAPS_DIFFICULTY_APOCALYPSE_DESCRIPTION";

		public const float ScalingValue = 4f;

		public const float MonsterAttackSpeed = 1.25f;

		public const float MonsterMoveSpeed = 1.2f;

		public const float PlayerRegen = 0.5f;

		internal static ConfigEntry<float> BlockBypassChance;

		internal static ConfigEntry<float> ApocalypseBlockBypassChance;

		public static DifficultyIndex Index = (DifficultyIndex)(-1);

		private static DifficultyDef def;

		private static Action<CharacterBody, float> setAttackSpeed;

		private static Action<CharacterBody, float> setMoveSpeed;

		private static Action<CharacterBody, float> setRegen;

		private static int fromDifficultyCalls;

		public static bool Active
		{
			get
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Invalid comparison between Unknown and I4
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if ((int)Index != -1 && (Object)(object)Run.instance != (Object)null)
				{
					return Run.instance.selectedDifficulty == Index;
				}
				return false;
			}
		}

		public static void Init(ConfigFile config, Harmony harmony)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Expected O, but got Unknown
			BlockBypassChance = config.Bind<float>("Block", "BlockBypassChance", 1f, "Шанс (%), что удар врага пробьёт блок урона: Крепкий орех или войдовый медведь (Safer Spaces).");
			ApocalypseBlockBypassChance = config.Bind<float>("Block", "ApocalypseBlockBypassChance", 5f, "То же на сложности «Апокалипсис».");
			AddDifficulty();
			Language.onCurrentLanguageChanged += AddStrings;
			AddStrings();
			setAttackSpeed = Setter("attackSpeed");
			setMoveSpeed = Setter("moveSpeed");
			setRegen = Setter("regen");
			harmony.Patch((MethodBase)AccessTools.Method(typeof(RuleDef), "FromDifficulty", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Apocalypse), "FromDifficultyPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(RuleCatalog), "Init", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Apocalypse), "RuleCatalogInitPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(CharacterBody), "RecalculateStats", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Apocalypse), "RecalculateStatsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(HealthComponent), "TakeDamageProcess", (Type[])null, (Type[])null), new HarmonyMethod(typeof(Apocalypse), "TakeDamagePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void AddDifficulty()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			FieldInfo fieldInfo = AccessTools.Field(typeof(DifficultyCatalog), "difficultyDefs");
			DifficultyDef[] array = (DifficultyDef[])fieldInfo.GetValue(null);
			DifficultyDef val = array[2];
			def = new DifficultyDef(4f, "LEVELCAPS_DIFFICULTY_APOCALYPSE_NAME", val.iconPath, "LEVELCAPS_DIFFICULTY_APOCALYPSE_DESCRIPTION", new Color(0.55f, 0.05f, 0.1f), "apoc", true);
			DifficultyDef[] array2 = (DifficultyDef[])(object)new DifficultyDef[array.Length + 1];
			Array.Copy(array, array2, array.Length);
			array2[array.Length] = def;
			Index = (DifficultyIndex)array.Length;
			fieldInfo.SetValue(null, array2);
		}

		private static void FromDifficultyPostfix(RuleDef __result)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_00c0: 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)
			fromDifficultyCalls++;
			if (def == null || __result == null || R2ApiAddsIt())
			{
				return;
			}
			foreach (RuleChoiceDef choice in __result.choices)
			{
				if (choice.difficultyIndex == Index || choice.localName == "Apocalypse")
				{
					return;
				}
			}
			RuleChoiceDef val = __result.AddChoice("Apocalypse", (object)null, false);
			val.spritePath = def.iconPath;
			val.tooltipNameToken = def.nameToken;
			val.tooltipNameColor = def.color;
			val.tooltipBodyToken = def.descriptionToken;
			val.difficultyIndex = Index;
			val.serverTag = def.serverTag;
			val.excludeByDefault = false;
		}

		private static bool R2ApiAddsIt()
		{
			Type type = Type.GetType("R2API.DifficultyAPI, R2API.Difficulty", throwOnError: false);
			if (type == null)
			{
				return false;
			}
			FieldInfo fieldInfo = AccessTools.Field(type, "_hooksEnabled");
			if (fieldInfo != null && fieldInfo.GetValue(null) is bool)
			{
				return (bool)fieldInfo.GetValue(null);
			}
			return false;
		}

		private static void RuleCatalogInitPostfix()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected I4, but got Unknown
			RuleDef val = RuleCatalog.FindRuleDef("Difficulty");
			if (val == null)
			{
				Debug.Log((object)"[LevelCaps] Правило Difficulty не найдено");
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			foreach (RuleChoiceDef choice in val.choices)
			{
				stringBuilder.Append(choice.localName).Append('(').Append((int)choice.difficultyIndex)
					.Append(choice.excludeByDefault ? ", скрыт" : "")
					.Append(") ");
			}
			Debug.Log((object)("[LevelCaps] Сложности в лобби (FromDifficulty вызван " + fromDifficultyCalls + " раз): " + stringBuilder));
		}

		private static void AddStrings()
		{
			Language currentLanguage = Language.currentLanguage;
			if (currentLanguage != null)
			{
				bool flag = (Language.currentLanguageName ?? "").StartsWith("ru", StringComparison.OrdinalIgnoreCase);
				currentLanguage.SetStringByToken("LEVELCAPS_DIFFICULTY_APOCALYPSE_NAME", flag ? "Апокалипсис" : "Apocalypse");
				currentLanguage.SetStringByToken("LEVELCAPS_DIFFICULTY_APOCALYPSE_DESCRIPTION", flag ? ("Для тех, кому мало Муссона.\n\n<style=cStack>>Сложность растёт на 33% быстрее, чем в Муссоне\n>Враги атакуют на 25% и двигаются на 20% быстрее\n>Базовая регенерация здоровья игроков снижена на 50%\n>Враги пробивают блок урона (Крепкий орех, войдовый медведь) с шансом " + ApocalypseBlockBypassChance.Value + "%</style>") : ("For those who find Monsoon too gentle.\n\n<style=cStack>>Difficulty scales 33% faster than Monsoon\n>Monsters attack 25% and move 20% faster\n>Player base health regeneration is halved\n>Monster hits pierce damage blocks (Tougher Times, Safer Spaces) " + ApocalypseBlockBypassChance.Value + "% of the time</style>"));
			}
		}

		private static Action<CharacterBody, float> Setter(string property)
		{
			MethodInfo method = AccessTools.PropertySetter(typeof(CharacterBody), property);
			return (Action<CharacterBody, float>)Delegate.CreateDelegate(typeof(Action<CharacterBody, float>), method);
		}

		private static void RecalculateStatsPostfix(CharacterBody __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Invalid comparison between Unknown and I4
			if (Active && !((Object)(object)__instance.teamComponent == (Object)null))
			{
				TeamIndex teamIndex = __instance.teamComponent.teamIndex;
				if ((int)teamIndex == 2 || (int)teamIndex == 4 || (int)teamIndex == 3)
				{
					setAttackSpeed(__instance, __instance.attackSpeed * 1.25f);
					setMoveSpeed(__instance, __instance.moveSpeed * 1.2f);
				}
				else if ((int)teamIndex == 1 && __instance.isPlayerControlled && __instance.regen > 0f)
				{
					setRegen(__instance, __instance.regen * 0.5f);
				}
			}
		}

		private static void TakeDamagePrefix(HealthComponent __instance, DamageInfo damageInfo)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_0087: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || damageInfo == null || (Object)(object)damageInfo.attacker == (Object)null)
			{
				return;
			}
			CharacterBody body = __instance.body;
			if ((Object)(object)body == (Object)null || !CanBlock(body))
			{
				return;
			}
			TeamComponent component = damageInfo.attacker.GetComponent<TeamComponent>();
			if (!((Object)(object)component == (Object)null) && (int)component.teamIndex != 1)
			{
				float num = (Active ? ApocalypseBlockBypassChance.Value : BlockBypassChance.Value);
				if (num > 0f && Random.value * 100f < num)
				{
					damageInfo.damageType |= DamageTypeCombo.op_Implicit((DamageType)64);
				}
			}
		}

		private static bool CanBlock(CharacterBody body)
		{
			if (body.HasBuff(Buffs.BearVoidReady))
			{
				return true;
			}
			if ((Object)(object)body.inventory != (Object)null)
			{
				return body.inventory.GetItemCount(Items.Bear) > 0;
			}
			return false;
		}
	}
}
namespace GameImprovement.Ui
{
	internal static class RoR2Ui
	{
		public static readonly Color BoxColor = new Color(0.09f, 0.1f, 0.12f, 0.96f);

		public static readonly Color MutedText = new Color(0.72f, 0.75f, 0.8f);

		public static readonly Color HeaderText = new Color(0.95f, 0.8f, 0.45f);

		private static readonly FieldInfo SubmenuField = AccessTools.Field(typeof(PauseScreenController), "submenuObject");

		public static GameObject AddPauseButton(PauseScreenController pause, string name, string label, UnityAction onClick)
		{
			GameObject exitGameButton = pause.exitGameButton;
			if ((Object)(object)exitGameButton == (Object)null)
			{
				return null;
			}
			GameObject val = CloneButton(exitGameButton, exitGameButton.transform.parent, label, onClick);
			((Object)val).name = name;
			val.transform.SetSiblingIndex(exitGameButton.transform.GetSiblingIndex());
			return val;
		}

		public static Submenu OpenSubmenu(PauseScreenController pause, string name, Vector2 anchorMin, Vector2 anchorMax)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			GameObject val = ((!(SubmenuField != null)) ? ((GameObject)null) : ((GameObject)SubmenuField.GetValue(pause)));
			if (Object.op_Implicit((Object)(object)val))
			{
				Object.Destroy((Object)(object)val);
			}
			GameObject val2 = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform val3 = (RectTransform)val2.transform;
			((Transform)val3).SetParent((Transform)(object)pause.rootPanel, false);
			Stretch(val3, Vector2.zero, Vector2.one);
			Image val4 = val2.AddComponent<Image>();
			((Graphic)val4).color = new Color(0f, 0f, 0f, 0.6f);
			RectTransform val5 = NewRect("Box", (Transform)(object)val3);
			Stretch(val5, anchorMin, anchorMax);
			((Graphic)((Component)val5).gameObject.AddComponent<Image>()).color = BoxColor;
			Outline val6 = ((Component)val5).gameObject.AddComponent<Outline>();
			((Shadow)val6).effectColor = new Color(0.55f, 0.6f, 0.65f, 0.6f);
			((Shadow)val6).effectDistance = new Vector2(2f, -2f);
			VerticalLayoutGroup val7 = ((Component)val5).gameObject.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val7).padding = new RectOffset(24, 24, 18, 18);
			((HorizontalOrVerticalLayoutGroup)val7).spacing = 10f;
			((HorizontalOrVerticalLayoutGroup)val7).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = false;
			if (SubmenuField != null)
			{
				SubmenuField.SetValue(pause, val2);
			}
			((Component)pause.pausePanel).gameObject.SetActive(false);
			((Component)pause.gameMenuPanel).gameObject.SetActive(true);
			((Component)pause.mainPanel).gameObject.SetActive(false);
			Submenu submenu = new Submenu();
			submenu.root = val2;
			submenu.box = val5;
			submenu.buttonTemplate = pause.exitGameButton;
			TextMeshProUGUI val8 = (((Object)(object)pause.exitGameButton != (Object)null) ? pause.exitGameButton.GetComponentInChildren<TextMeshProUGUI>(true) : null);
			submenu.font = (((Object)(object)val8 != (Object)null) ? ((TMP_Text)val8).font : null);
			return submenu;
		}

		public static GameObject CloneButton(GameObject template, Transform parent, string label, UnityAction onClick)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(template, parent);
			LanguageTextMeshController[] componentsInChildren = val.GetComponentsInChildren<LanguageTextMeshController>(true);
			foreach (LanguageTextMeshController val2 in componentsInChildren)
			{
				Object.DestroyImmediate((Object)(object)val2);
			}
			SetButtonText(val, label);
			Button component = val.GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				component.onClick = new ButtonClickedEvent();
				if (onClick != null)
				{
					((UnityEvent)component.onClick).AddListener(onClick);
				}
			}
			val.SetActive(true);
			return val;
		}

		public static void SetButtonText(GameObject button, string label)
		{
			TextMeshProUGUI[] componentsInChildren = button.GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val in componentsInChildren)
			{
				((TMP_Text)val).text = label;
			}
		}

		public static RectTransform NewRect(string name, Transform parent)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(parent, false);
			return val2;
		}

		public static void Stretch(RectTransform rt, Vector2 min, Vector2 max)
		{
			//IL_0001: 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_000f: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = min;
			rt.anchorMax = max;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
			((Transform)rt).localScale = Vector3.one;
		}

		public static LayoutElement Size(GameObject go, float height, float width)
		{
			LayoutElement val = go.GetComponent<LayoutElement>();
			if ((Object)(object)val == (Object)null)
			{
				val = go.AddComponent<LayoutElement>();
			}
			if (height >= 0f)
			{
				val.minHeight = height;
				val.preferredHeight = height;
				val.flexibleHeight = 0f;
			}
			if (width >= 0f)
			{
				val.minWidth = width;
				val.preferredWidth = width;
				val.flexibleWidth = 0f;
			}
			return val;
		}
	}
	internal class Submenu
	{
		public const float ButtonHeight = 46f;

		public GameObject root;

		public RectTransform box;

		public GameObject buttonTemplate;

		public TMP_FontAsset font;

		public void Close()
		{
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
		}

		public TextMeshProUGUI Text(Transform parent, string text, float size, TextAlignmentOptions align, Color color)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = RoR2Ui.NewRect("Text", parent);
			TextMeshProUGUI val2 = ((Component)val).gameObject.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val2).font = font;
			}
			((TMP_Text)val2).text = text;
			((TMP_Text)val2).fontSize = size;
			((TMP_Text)val2).alignment = align;
			((Graphic)val2).color = color;
			((Graphic)val2).raycastTarget = false;
			((TMP_Text)val2).enableWordWrapping = true;
			return val2;
		}

		public TextMeshProUGUI Title(string text)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = Text((Transform)(object)box, text, 38f, (TextAlignmentOptions)514, Color.white);
			RoR2Ui.Size(((Component)val).gameObject, 48f, -1f);
			return val;
		}

		public GameObject Button(Transform parent, string label, UnityAction onClick)
		{
			GameObject val = RoR2Ui.CloneButton(buttonTemplate, parent, label, onClick);
			LayoutElement val2 = RoR2Ui.Size(val, 46f, -1f);
			val2.minWidth = 0f;
			val2.preferredWidth = 0f;
			val2.flexibleWidth = 1f;
			TextMeshProUGUI[] componentsInChildren = val.GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val3 in componentsInChildren)
			{
				((TMP_Text)val3).enableAutoSizing = true;
				((TMP_Text)val3).fontSizeMin = 12f;
				((TMP_Text)val3).fontSizeMax = 20f;
				((TMP_Text)val3).enableWordWrapping = false;
			}
			return val;
		}

		public RectTransform Row(Transform parent, float height)
		{
			RectTransform val = RoR2Ui.NewRect("Row", parent);
			RoR2Ui.Size(((Component)val).gameObject, height, -1f);
			HorizontalLayoutGroup val2 = ((Component)val).gameObject.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val2).spacing = 10f;
			((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = true;
			((LayoutGroup)val2).childAlignment = (TextAnchor)3;
			return val;
		}

		public TMP_InputField Input(Transform parent, string value, float width, UnityAction<string> onEndEdit)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = RoR2Ui.NewRect("Input", parent);
			Image val2 = ((Component)val).gameObject.AddComponent<Image>();
			((Graphic)val2).color = new Color(0.02f, 0.03f, 0.04f, 0.9f);
			Outline val3 = ((Component)val).gameObject.AddComponent<Outline>();
			((Shadow)val3).effectColor = new Color(0.45f, 0.5f, 0.55f, 0.7f);
			LayoutElement val4 = RoR2Ui.Size(((Component)val).gameObject, 40f, width);
			if (width < 0f)
			{
				val4.flexibleWidth = 1f;
			}
			RectTransform val5 = RoR2Ui.NewRect("Text Area", (Transform)(object)val);
			RoR2Ui.Stretch(val5, Vector2.zero, Vector2.one);
			val5.offsetMin = new Vector2(10f, 4f);
			val5.offsetMax = new Vector2(-10f, -4f);
			((Component)val5).gameObject.AddComponent<RectMask2D>();
			TextMeshProUGUI val6 = Text((Transform)(object)val5, "", 20f, (TextAlignmentOptions)4097, Color.white);
			((TMP_Text)val6).enableWordWrapping = false;
			RoR2Ui.Stretch(((TMP_Text)val6).rectTransform, Vector2.zero, Vector2.one);
			TMP_InputField val7 = ((Component)val).gameObject.AddComponent<TMP_InputField>();
			val7.textViewport = val5;
			val7.textComponent = (TMP_Text)(object)val6;
			if ((Object)(object)font != (Object)null)
			{
				val7.fontAsset = font;
			}
			val7.pointSize = 20f;
			((Selectable)val7).targetGraphic = (Graphic)(object)val2;
			val7.text = value ?? "";
			if (onEndEdit != null)
			{
				((UnityEvent<string>)(object)val7.onEndEdit).AddListener(onEndEdit);
			}
			return val7;
		}

		public RectTransform ScrollList(Transform parent)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			RectTransform val = RoR2Ui.NewRect("Scroll", parent);
			LayoutElement val2 = ((Component)val).gameObject.AddComponent<LayoutElement>();
			val2.flexibleHeight = 1f;
			val2.minHeight = 120f;
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.35f);
			((Component)val).gameObject.AddComponent<RectMask2D>();
			ScrollRect val3 = ((Component)val).gameObject.AddComponent<ScrollRect>();
			val3.horizontal = false;
			val3.movementType = (MovementType)2;
			val3.scrollSensitivity = 40f;
			RectTransform val4 = RoR2Ui.NewRect("Content", (Transform)(object)val);
			val4.anchorMin = new Vector2(0f, 1f);
			val4.anchorMax = new Vector2(1f, 1f);
			val4.pivot = new Vector2(0.5f, 1f);
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			VerticalLayoutGroup val5 = ((Component)val4).gameObject.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val5).padding = new RectOffset(16, 16, 10, 14);
			((HorizontalOrVerticalLayoutGroup)val5).spacing = 4f;
			((HorizontalOrVerticalLayoutGroup)val5).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)val5).childForceExpandHeight = false;
			ContentSizeFitter val6 = ((Component)val4).gameObject.AddComponent<ContentSizeFitter>();
			val6.verticalFit = (FitMode)2;
			val3.content = val4;
			val3.viewport = val;
			return val4;
		}

		public static void Clear(Transform parent)
		{
			for (int num = parent.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)parent.GetChild(num)).gameObject);
			}
		}
	}
}