Decompiled source of DirectorReworkPlus v1.0.2

DirectorRework.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DirectorRework.Config;
using DirectorRework.Cruelty;
using DirectorRework.Hooks;
using EntityStates;
using Microsoft.CodeAnalysis;
using On.RoR2;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DirectorRework")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+63b89e2c6d1010600c62ce196a31f4f2d6fa3d58")]
[assembly: AssemblyProduct("DirectorRework")]
[assembly: AssemblyTitle("DirectorRework")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DirectorRework
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.score.DirectorReworkPlus", "DirectorReworkPlus", "1.0.2")]
	public class DirectorReworkPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.score.DirectorReworkPlus";

		public const string PluginAuthor = "score";

		public const string PluginName = "DirectorReworkPlus";

		public const string PluginVersion = "1.0.2";

		public static DirectorReworkPlugin Instance { get; private set; }

		public void Awake()
		{
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			PluginConfig.Init(((BaseUnityPlugin)this).Config);
			if (PluginConfig.enableCruelty.Value)
			{
				CrueltyManager.Init();
			}
			if (PluginConfig.enableDirectorMain.Value)
			{
				DirectorMain.Init();
			}
			if (PluginConfig.enableDirectorTweaks.Value)
			{
				DirectorTweaks.Init();
			}
		}
	}
	public static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		public static void Debug(string data)
		{
			_logSource.LogDebug((object)data);
		}

		public static void Error(string data)
		{
			_logSource.LogError((object)data);
		}

		public static void Fatal(string data)
		{
			_logSource.LogFatal((object)data);
		}

		public static void Info(string data)
		{
			_logSource.LogInfo((object)data);
		}

		public static void Message(string data)
		{
			_logSource.LogMessage((object)data);
		}

		public static void Warning(string data)
		{
			_logSource.LogWarning((object)data);
		}
	}
}
namespace DirectorRework.Config
{
	public static class PluginConfig
	{
		public static ConfigFile MainConfig;

		public static ConfigEntry<bool> info;

		public static ConfigEntry<bool> enableCruelty;

		public static ConfigEntry<bool> enableDirectorMain;

		public static ConfigEntry<bool> enableDirectorTweaks;

		public static ConfigEntry<int> maxAffixes;

		public static ConfigEntry<bool> guaranteeSpecialBoss;

		public static ConfigEntry<bool> onlyApplyToElites;

		public static ConfigEntry<int> triggerChance;

		public static ConfigEntry<int> successChance;

		public static ConfigEntry<bool> enableSpawnDiversity;

		public static ConfigEntry<bool> enableVieldsDiversity;

		public static ConfigEntry<bool> enableCreditRefund;

		public static ConfigEntry<int> creditRefundMultiplier;

		public static ConfigEntry<float> minimumRerollSpawnIntervalMultiplier;

		public static ConfigEntry<float> maximumRerollSpawnIntervalMultiplier;

		public static ConfigEntry<float> creditMultiplier;

		public static ConfigEntry<float> eliteBiasMultiplier;

		public static ConfigEntry<float> creditMultiplierForEachMountainShrine;

		public static ConfigEntry<float> goldAndExperienceMultiplierForEachMountainShrine;

		public static ConfigEntry<int> maximumNumberToSpawnBeforeSkipping;

		public static ConfigEntry<int> maxConsecutiveCheapSkips;

		public static void Init(ConfigFile cfg)
		{
			MainConfig = cfg;
			ModSettingsManager.SetModDescription("Director Rework Plus Essentially.");
			string section = "Modules";
			enableCruelty = cfg.BindOption(section, "Enable Affix Stacking", defaultValue: true, "Enables Affix Stacking (highly inspired by Artifact of Cruelty in RiskyArtifacts). Disable to prevent all modifications in 'Affixes/Cruelty' from loading.", restartRequired: true);
			enableDirectorMain = cfg.BindOption(section, "Enable Director Changes", defaultValue: true, "Enables Enemy Variety and all 'Director Main' config options. Disable to prevent all modifications in 'Director Main' from loading.", restartRequired: true);
			enableDirectorTweaks = cfg.BindOption(section, "Enable Combat Director Tweaks", defaultValue: true, "Enables a variety of configurable Combat Director options. Intended for fine tuning the pacing of spawns. Disable to prevent all modifications in 'Director Tweaks' from loading.", restartRequired: true);
			section = "Affixes/Cruelty";
			maxAffixes = cfg.BindOptionSlider(section, "Max Additional Affixes", 4, "Maximum Affixes that an enemy can have. Combat Director will still need to afford the combined credit cost of the new enemy.", 1f, 10f);
			guaranteeSpecialBoss = cfg.BindOption(section, "Guarantee Special Boss", defaultValue: true, "Always apply additional affixes to special bosses. Applies to void cradles and ignores elite credit cost.");
			triggerChance = cfg.BindOptionSlider(section, "Trigger Chance", 25, "Chance to apply the first additional affix to an enemy. Set to 100 to make it always apply.", 0f, 100f);
			successChance = cfg.BindOptionSlider(section, "Additional Affix Chance", 25, "Chance to add an additional affix after the first. Set to 100 to make it always attempt to add as many affixes as possible.", 0f, 100f);
			onlyApplyToElites = cfg.BindOption(section, "Only Apply to Elites", defaultValue: true, "Only applies additional affixes to enemies that are already elite. Setting this to false will increase the occurrance of elites as a whole.");
			section = "Director Main";
			enableSpawnDiversity = cfg.BindOption(section, "Enable Spawn Diversity", defaultValue: true, "Spawns multiple enemy types per wave, multiple boss types during teleporter, etc.");
			enableVieldsDiversity = cfg.BindOption(section, "Enable Void Fields Spawn Diversity", defaultValue: false, "Spawns multiple enemy types in void fields. Requires 'Enable Spawn Diversity'.");
			enableCreditRefund = cfg.BindOption(section, "Enable Credit Refund", defaultValue: true, "Gives combat director back a percent of credits spent on spawns. Might work better when the enemy dies but this is good enough for now.");
			creditRefundMultiplier = cfg.BindOption(section, "Percent refund to give to the combat director for a successfully spawned enemy.", 15, "Amount to refund the combat director when spawning enemies, in percent. 100 is a bad idea, but its technically possible.");
			section = "Director Tweaks";
			creditMultiplier = cfg.BindOptionSlider(section, "Credit Multiplier", 1f, "How much to multiply money wave yield by.");
			eliteBiasMultiplier = cfg.BindOptionSlider(section, "Elite Bias Cost Multiplier", 1f, "Multiplies the elite selection cost. Higher numbers result in higher cost and therefore less elites.");
			minimumRerollSpawnIntervalMultiplier = cfg.BindOptionSlider(section, "Minimum Reroll Spawn Interval", 2.3333333f, "Used when a spawn is rejected and the director needs to wait to build more credits.");
			maximumRerollSpawnIntervalMultiplier = cfg.BindOptionSlider(section, "Maximum Reroll Spawn Interval", 4.3333335f, "Used when a spawn is rejected and the director needs to wait to build more credits.");
			creditMultiplierForEachMountainShrine = cfg.BindOptionSlider(section, "Credit Multiplier For Each Mountain Shrine", 1f, "Credit multiplier for the teleporter director for each mountain shrine");
			goldAndExperienceMultiplierForEachMountainShrine = cfg.BindOptionSlider(section, "Gold And Experience Multiplier For Each Mountain Shrine", 1f, "Gold and Exp multiplier for the teleporter director for each mountain shrine");
			maximumNumberToSpawnBeforeSkipping = cfg.BindOptionSlider(section, "Maximum Number To Spawn Before Skipping", 6, "Maximum number of enemies in a single wave. If the director can afford more than this, it'll reroll the spawncard.");
			maxConsecutiveCheapSkips = cfg.BindOptionSlider(section, "Max Consecutive Cheap Skips", -1, "If skipSpawnIfTooCheap is true, we'll behave as though it's not set after this many consecutive skips.", -1f);
		}

		public static ConfigEntry<T> BindOption<T>(this ConfigFile myConfig, string section, string name, T defaultValue, string description = "", bool restartRequired = false)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = name;
			}
			if (restartRequired)
			{
				description += " (restart required)";
			}
			ConfigEntry<T> obj = myConfig.Bind<T>(section, name, defaultValue, description);
			TryRegisterOption<T>(obj, restartRequired);
			return obj;
		}

		public static ConfigEntry<T> BindOptionSlider<T>(this ConfigFile myConfig, string section, string name, T defaultValue, string description = "", float min = 0f, float max = 20f, bool restartRequired = false)
		{
			if (string.IsNullOrEmpty(description))
			{
				description = name;
			}
			string text = description;
			T val = defaultValue;
			description = text + " (Default: " + val?.ToString() + ")";
			if (restartRequired)
			{
				description += " (restart required)";
			}
			ConfigEntry<T> obj = myConfig.Bind<T>(section, name, defaultValue, description);
			TryRegisterOptionSlider<T>(obj, min, max, restartRequired);
			return obj;
		}

		public static void TryRegisterOption<T>(ConfigEntry<T> entry, bool restartRequired)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			if (entry is ConfigEntry<string> val)
			{
				ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(val, restartRequired));
			}
			else if (entry is ConfigEntry<float> val2)
			{
				ModSettingsManager.AddOption((BaseOption)new SliderOption(val2, new SliderConfig
				{
					min = 0f,
					max = 20f,
					formatString = "{0:0.00}",
					restartRequired = restartRequired
				}));
			}
			else if (entry is ConfigEntry<int> val3)
			{
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(val3, restartRequired));
			}
			else if (entry is ConfigEntry<bool> val4)
			{
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(val4, restartRequired));
			}
			else if (entry is ConfigEntry<KeyboardShortcut> val5)
			{
				ModSettingsManager.AddOption((BaseOption)new KeyBindOption(val5, restartRequired));
			}
			else if (typeof(T).IsEnum)
			{
				ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)entry, restartRequired));
			}
		}

		public static void TryRegisterOptionSlider<T>(ConfigEntry<T> entry, float min, float max, bool restartRequired)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0037: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (entry is ConfigEntry<int> val)
			{
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(val, new IntSliderConfig
				{
					min = (int)min,
					max = (int)max,
					formatString = "{0:0.00}",
					restartRequired = restartRequired
				}));
			}
			else if (entry is ConfigEntry<float> val2)
			{
				ModSettingsManager.AddOption((BaseOption)new SliderOption(val2, new SliderConfig
				{
					min = min,
					max = max,
					formatString = "{0:0.00}",
					restartRequired = restartRequired
				}));
			}
		}
	}
}
namespace DirectorRework.Hooks
{
	internal class DirectorMain
	{
		public static DirectorMain instance;

		public static void Init()
		{
			if (instance == null)
			{
				instance = new DirectorMain();
			}
		}

		private DirectorMain()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			CombatDirector.Spawn += new hook_Spawn(CombatDirector_Spawn);
			CombatDirector.Simulate += new hook_Simulate(CombatDirector_Simulate);
			Chat.SendBroadcastChat_ChatMessageBase += new hook_SendBroadcastChat_ChatMessageBase(ChangeMessage);
			BossGroup.UpdateBossMemories += new hook_UpdateBossMemories(UpdateTitle);
		}

		private void CombatDirector_Simulate(orig_Simulate orig, CombatDirector self, float deltaTime)
		{
			orig.Invoke(self, deltaTime);
			if ((PluginConfig.enableVieldsDiversity.Value || !Object.op_Implicit((Object)(object)ArenaMissionController.instance)) && PluginConfig.enableSpawnDiversity.Value && self.currentMonsterCard != null)
			{
				float monsterSpawnTimer = self.monsterSpawnTimer;
				int spawnCountInCurrentWave = self.spawnCountInCurrentWave;
				if ((Object)(object)self == (Object)(object)TeleporterInteraction.instance?.bossDirector)
				{
					self.SetNextSpawnAsBoss();
				}
				else if (self.finalMonsterCardsSelection != null && self.finalMonsterCardsSelection.Count > 0)
				{
					self.PrepareNewMonsterWave(self.finalMonsterCardsSelection.Evaluate(self.rng.nextNormalizedFloat));
				}
				self.monsterSpawnTimer = monsterSpawnTimer;
				self.spawnCountInCurrentWave = spawnCountInCurrentWave;
			}
		}

		private void ChangeMessage(orig_SendBroadcastChat_ChatMessageBase orig, ChatMessageBase message)
		{
			if (PluginConfig.enableSpawnDiversity.Value)
			{
				SubjectFormatChatMessage val = (SubjectFormatChatMessage)(object)((message is SubjectFormatChatMessage) ? message : null);
				if (val != null)
				{
					bool? flag = val.paramTokens?.Any();
					if (flag.HasValue && flag.GetValueOrDefault() && ((SubjectChatMessage)val).baseToken == "SHRINE_COMBAT_USE_MESSAGE")
					{
						val.paramTokens[0] = Language.GetString("LOGBOOK_CATEGORY_MONSTER").ToLower();
					}
				}
			}
			orig.Invoke(message);
		}

		private void UpdateTitle(orig_UpdateBossMemories orig, BossGroup self)
		{
			orig.Invoke(self);
			if (!PluginConfig.enableSpawnDiversity.Value)
			{
				return;
			}
			Dictionary<(string, string), float> dictionary = new Dictionary<(string, string), float>();
			float num = 0f;
			for (int i = 0; i < self.bossMemoryCount; i++)
			{
				CharacterBody cachedBody = self.bossMemories[i].cachedBody;
				if (!Object.op_Implicit((Object)(object)cachedBody))
				{
					continue;
				}
				HealthComponent healthComponent = cachedBody.healthComponent;
				if (!Object.op_Implicit((Object)(object)healthComponent) || !healthComponent.alive)
				{
					continue;
				}
				string bestBodyName = Util.GetBestBodyName(((Component)cachedBody).gameObject);
				string text = cachedBody.GetSubtitle();
				(string, string) key = (bestBodyName, text);
				if (!dictionary.ContainsKey(key))
				{
					dictionary[key] = 0f;
				}
				dictionary[key] += healthComponent.combinedHealth + healthComponent.missingCombinedHealth * 4f;
				if (dictionary[key] > num)
				{
					num = dictionary[key];
					if (string.IsNullOrEmpty(text))
					{
						text = Language.GetString("NULL_SUBTITLE");
					}
					self.bestObservedName = bestBodyName;
					self.bestObservedSubtitle = "<sprite name=\"CloudLeft\" tint=1> " + text + " <sprite name=\"CloudRight\" tint=1>";
				}
			}
		}

		private bool CombatDirector_Spawn(orig_Spawn orig, CombatDirector self, SpawnCard spawnCard, EliteDef eliteDef, Transform spawnTarget, MonsterSpawnDistance spawnDistance, bool preventOverhead, float valueMultiplier, PlacementMode placementMode)
		{
			//IL_0007: 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)
			bool num = orig.Invoke(self, spawnCard, eliteDef, spawnTarget, spawnDistance, preventOverhead, valueMultiplier, placementMode);
			if (num && PluginConfig.enableCreditRefund.Value)
			{
				float num2 = (float)PluginConfig.creditRefundMultiplier.Value * 0.01f * (float)spawnCard.directorCreditCost * valueMultiplier;
				self.monsterCredit += num2;
				self.totalCreditsSpent += num2;
			}
			return num;
		}
	}
	internal class DirectorTweaks
	{
		public static DirectorTweaks instance;

		public static void Init()
		{
			if (instance == null)
			{
				instance = new DirectorTweaks();
			}
		}

		private DirectorTweaks()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			CombatDirector.Awake += new hook_Awake(CombatDirector_Awake);
			ChargingState.OnEnter += new hook_OnEnter(ChargingState_OnEnter);
		}

		private void ChargingState_OnEnter(orig_OnEnter orig, BaseState self)
		{
			ChargingState val = (ChargingState)(object)((self is ChargingState) ? self : null);
			if (val != null && val != null && Object.op_Implicit((Object)(object)((BaseTeleporterState)val).teleporterInteraction))
			{
				int shrineBonusStacks = ((BaseTeleporterState)val).teleporterInteraction.shrineBonusStacks;
				if (shrineBonusStacks > 0)
				{
					CombatDirector bossDirector = val.bossDirector;
					if (Object.op_Implicit((Object)(object)bossDirector))
					{
						CombatDirector obj = bossDirector;
						obj.creditMultiplier *= (float)shrineBonusStacks * PluginConfig.creditMultiplierForEachMountainShrine.Value;
						CombatDirector obj2 = bossDirector;
						obj2.expRewardCoefficient *= (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.Value;
						CombatDirector obj3 = bossDirector;
						obj3.goldRewardCoefficient *= (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.Value;
					}
					bossDirector = val.bonusDirector;
					if (Object.op_Implicit((Object)(object)bossDirector))
					{
						CombatDirector obj4 = bossDirector;
						obj4.creditMultiplier *= (float)shrineBonusStacks * PluginConfig.creditMultiplierForEachMountainShrine.Value;
						CombatDirector obj5 = bossDirector;
						obj5.expRewardCoefficient *= (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.Value;
						CombatDirector obj6 = bossDirector;
						obj6.goldRewardCoefficient *= (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.Value;
					}
				}
			}
			orig.Invoke(self);
		}

		private void CombatDirector_Awake(orig_Awake orig, CombatDirector self)
		{
			if (PluginConfig.maxConsecutiveCheapSkips.Value >= 0)
			{
				self.maxConsecutiveCheapSkips = PluginConfig.maxConsecutiveCheapSkips.Value;
			}
			self.maximumNumberToSpawnBeforeSkipping = PluginConfig.maximumNumberToSpawnBeforeSkipping.Value;
			self.minRerollSpawnInterval = PluginConfig.minimumRerollSpawnIntervalMultiplier.Value;
			self.maxRerollSpawnInterval = PluginConfig.maximumRerollSpawnIntervalMultiplier.Value;
			self.creditMultiplier *= PluginConfig.creditMultiplier.Value;
			self.eliteBias *= PluginConfig.eliteBiasMultiplier.Value;
			orig.Invoke(self);
		}
	}
}
namespace DirectorRework.Cruelty
{
	public static class CombatCruelty
	{
		public static void OnSpawnedServer(CombatDirector director, GameObject masterObject)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Invalid comparison between Unknown and I4
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			if (!Util.CheckRoll((float)PluginConfig.triggerChance.Value, 0f, (CharacterMaster)null))
			{
				return;
			}
			CharacterMaster val = (Object.op_Implicit((Object)(object)masterObject) ? masterObject.GetComponent<CharacterMaster>() : null);
			if (!Object.op_Implicit((Object)(object)val) || !val.hasBody)
			{
				return;
			}
			CharacterBody body = val.GetBody();
			Inventory inventory = val.inventory;
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)inventory) || inventory.GetItemCount(Items.HealthDecay) > 0)
			{
				return;
			}
			List<BuffIndex> list = new List<BuffIndex>();
			BuffIndex[] eliteBuffIndices = BuffCatalog.eliteBuffIndices;
			foreach (BuffIndex val2 in eliteBuffIndices)
			{
				if (body.HasBuff(val2) && !list.Contains(val2))
				{
					list.Add(val2);
				}
			}
			if (PluginConfig.onlyApplyToElites.Value && !list.Any())
			{
				return;
			}
			DeathRewards component = ((Component)body).GetComponent<DeathRewards>();
			uint num = 0u;
			uint num2 = 0u;
			if (Object.op_Implicit((Object)(object)component))
			{
				num = component.expReward;
				num2 = component.goldReward;
			}
			(EliteDef, float) result;
			while (director.monsterCredit > 0f && list.Count < PluginConfig.maxAffixes.Value && GetRandom(director.monsterCredit, director.currentMonsterCard, director.rng, list, out result))
			{
				if ((int)inventory.currentEquipmentIndex == -1)
				{
					inventory.SetEquipmentIndex(result.Item1.eliteEquipmentDef.equipmentIndex);
				}
				BuffIndex buffIndex = result.Item1.eliteEquipmentDef.passiveBuffDef.buffIndex;
				list.Add(buffIndex);
				body.AddBuff(buffIndex);
				float num3 = list.Count;
				director.monsterCredit -= result.Item2 / num3;
				inventory.GiveItem(Items.BoostHp, Mathf.RoundToInt((result.Item1.healthBoostCoefficient - 1f) * 10f / num3));
				inventory.GiveItem(Items.BoostDamage, Mathf.RoundToInt((result.Item1.damageBoostCoefficient - 1f) * 10f / num3));
				if (Object.op_Implicit((Object)(object)component))
				{
					component.expReward += Convert.ToUInt32((float)num / num3);
					component.goldReward += Convert.ToUInt32((float)num2 / num3);
				}
				if (!Util.CheckRoll((float)PluginConfig.successChance.Value, 0f, (CharacterMaster)null))
				{
					break;
				}
			}
		}

		private static bool GetRandom(float availableCredits, DirectorCard card, Xoroshiro128Plus rng, List<BuffIndex> currentBuffs, out (EliteDef def, float cost) result)
		{
			result = default((EliteDef, float));
			EliteTierDef[] eliteTiers = CombatDirector.eliteTiers;
			if (eliteTiers == null || eliteTiers.Length == 0)
			{
				return false;
			}
			DirectorCard obj = card;
			int cost = ((obj != null) ? obj.cost : 0);
			IEnumerable<(EliteDef, float)> source = from etd in eliteTiers
				where IsValid(etd, card, cost, availableCredits, currentBuffs.Count)
				from ed in etd.availableDefs
				where CrueltyManager.IsValid(ed, currentBuffs)
				select (ed, etd.costMultiplier * (float)cost);
			if (source.Any())
			{
				int index = rng.RangeInt(0, source.Count());
				result = source.ElementAt(index);
				return true;
			}
			return false;
		}

		private static bool IsValid(EliteTierDef etd, DirectorCard card, int cost, float availableCredits, int affixes)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			bool flag = availableCredits >= (float)cost * etd.costMultiplier / (float)(affixes + 1);
			if (etd != null && !etd.canSelectWithoutAvailableEliteDef && flag)
			{
				if (card != null)
				{
					return etd.CanSelect(card.spawnCard.eliteRules);
				}
				return true;
			}
			return false;
		}
	}
	public class CrueltyManager
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Awake <>9__6_0;

			public static hook_Awake <>9__6_1;

			internal void <.ctor>b__6_0(orig_Awake orig, CombatDirector self)
			{
				<>c__DisplayClass6_0 CS$<>8__locals0 = new <>c__DisplayClass6_0
				{
					self = self
				};
				orig.Invoke(CS$<>8__locals0.self);
				if (NetworkServer.active)
				{
					((UnityEvent<GameObject>)(object)CS$<>8__locals0.self.onSpawnedServer).AddListener((UnityAction<GameObject>)delegate(GameObject masterObject)
					{
						CombatCruelty.OnSpawnedServer(CS$<>8__locals0.self, masterObject);
					});
				}
			}

			internal void <.ctor>b__6_1(orig_Awake orig, ScriptedCombatEncounter self)
			{
				<>c__DisplayClass6_1 CS$<>8__locals0 = new <>c__DisplayClass6_1
				{
					self = self
				};
				orig.Invoke(CS$<>8__locals0.self);
				if (NetworkServer.active && Object.op_Implicit((Object)(object)CS$<>8__locals0.self.combatSquad))
				{
					CS$<>8__locals0.self.combatSquad.onMemberAddedServer += delegate(CharacterMaster master)
					{
						ScriptedCruelty.OnMemberAddedServer(master, CS$<>8__locals0.self.rng);
					};
				}
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass6_0
		{
			public CombatDirector self;

			internal void <.ctor>b__2(GameObject masterObject)
			{
				CombatCruelty.OnSpawnedServer(self, masterObject);
			}
		}

		[CompilerGenerated]
		private sealed class <>c__DisplayClass6_1
		{
			public ScriptedCombatEncounter self;

			internal void <.ctor>b__3(CharacterMaster master)
			{
				ScriptedCruelty.OnMemberAddedServer(master, self.rng);
			}
		}

		public static HashSet<EquipmentIndex> BlacklistedElites = new HashSet<EquipmentIndex>();

		public static CrueltyManager Instance { get; private set; }

		public static void Init()
		{
			if (Instance == null)
			{
				Instance = new CrueltyManager();
			}
		}

		private CrueltyManager()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_006d: 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_0078: Expected O, but got Unknown
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnLoad));
			object obj = <>c.<>9__6_0;
			if (obj == null)
			{
				hook_Awake val = delegate(orig_Awake orig, CombatDirector self)
				{
					orig.Invoke(self);
					if (NetworkServer.active)
					{
						((UnityEvent<GameObject>)(object)self.onSpawnedServer).AddListener((UnityAction<GameObject>)delegate(GameObject masterObject)
						{
							CombatCruelty.OnSpawnedServer(self, masterObject);
						});
					}
				};
				<>c.<>9__6_0 = val;
				obj = (object)val;
			}
			CombatDirector.Awake += (hook_Awake)obj;
			object obj2 = <>c.<>9__6_1;
			if (obj2 == null)
			{
				hook_Awake val2 = delegate(orig_Awake orig, ScriptedCombatEncounter self)
				{
					orig.Invoke(self);
					if (NetworkServer.active && Object.op_Implicit((Object)(object)self.combatSquad))
					{
						self.combatSquad.onMemberAddedServer += delegate(CharacterMaster master)
						{
							ScriptedCruelty.OnMemberAddedServer(master, self.rng);
						};
					}
				};
				<>c.<>9__6_1 = val2;
				obj2 = (object)val2;
			}
			ScriptedCombatEncounter.Awake += (hook_Awake)obj2;
		}

		private static void OnLoad()
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_000f: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			EquipmentIndex val = EquipmentCatalog.FindEquipmentIndex("AffixBlightedMoffein");
			if ((int)val != -1)
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(val);
				if (Object.op_Implicit((Object)(object)equipmentDef) && Object.op_Implicit((Object)(object)equipmentDef.passiveBuffDef) && Object.op_Implicit((Object)(object)equipmentDef.passiveBuffDef.eliteDef))
				{
					BlacklistedElites.Add(val);
				}
			}
			EquipmentIndex val2 = EquipmentCatalog.FindEquipmentIndex("EliteLunarEquipment");
			if ((int)val2 != -1)
			{
				EquipmentDef equipmentDef2 = EquipmentCatalog.GetEquipmentDef(val2);
				if (Object.op_Implicit((Object)(object)equipmentDef2) && Object.op_Implicit((Object)(object)equipmentDef2.passiveBuffDef) && Object.op_Implicit((Object)(object)equipmentDef2.passiveBuffDef.eliteDef))
				{
					BlacklistedElites.Add(val2);
				}
			}
		}

		internal static bool IsValid(EliteDef ed, List<BuffIndex> currentBuffs)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)ed) && ed.IsAvailable() && Object.op_Implicit((Object)(object)ed.eliteEquipmentDef) && Object.op_Implicit((Object)(object)ed.eliteEquipmentDef.passiveBuffDef) && ed.eliteEquipmentDef.passiveBuffDef.isElite && !BlacklistedElites.Contains(ed.eliteEquipmentDef.equipmentIndex))
			{
				return !currentBuffs.Contains(ed.eliteEquipmentDef.passiveBuffDef.buffIndex);
			}
			return false;
		}
	}
	public static class ScriptedCruelty
	{
		public static void OnMemberAddedServer(CharacterMaster master, Xoroshiro128Plus rng)
		{
			//IL_007a: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00f5: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			if ((!PluginConfig.guaranteeSpecialBoss.Value && !Util.CheckRoll((float)PluginConfig.triggerChance.Value, 0f, (CharacterMaster)null)) || !Object.op_Implicit((Object)(object)master) || !master.hasBody)
			{
				return;
			}
			CharacterBody body = master.GetBody();
			Inventory inventory = master.inventory;
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)inventory) || inventory.GetItemCount(Items.HealthDecay) > 0)
			{
				return;
			}
			List<BuffIndex> list = new List<BuffIndex>();
			BuffIndex[] eliteBuffIndices = BuffCatalog.eliteBuffIndices;
			foreach (BuffIndex val in eliteBuffIndices)
			{
				if (body.HasBuff(val) && !list.Contains(val))
				{
					list.Add(val);
				}
			}
			DeathRewards component = ((Component)body).GetComponent<DeathRewards>();
			uint num = 0u;
			uint num2 = 0u;
			if (Object.op_Implicit((Object)(object)component))
			{
				num = component.expReward;
				num2 = component.goldReward;
			}
			EliteDef result;
			while (list.Count < PluginConfig.maxAffixes.Value && GetScriptedRandom(rng, list, out result))
			{
				if ((int)inventory.currentEquipmentIndex == -1)
				{
					inventory.SetEquipmentIndex(result.eliteEquipmentDef.equipmentIndex);
				}
				BuffIndex buffIndex = result.eliteEquipmentDef.passiveBuffDef.buffIndex;
				list.Add(buffIndex);
				body.AddBuff(buffIndex);
				float num3 = list.Count;
				inventory.GiveItem(Items.BoostHp, Mathf.RoundToInt((result.healthBoostCoefficient - 1f) * 10f / num3));
				inventory.GiveItem(Items.BoostDamage, Mathf.RoundToInt((result.damageBoostCoefficient - 1f) * 10f / num3));
				if (Object.op_Implicit((Object)(object)component))
				{
					component.expReward += Convert.ToUInt32((float)num / num3);
					component.goldReward += Convert.ToUInt32((float)num2 / num3);
				}
				if (!Util.CheckRoll((float)PluginConfig.successChance.Value, 0f, (CharacterMaster)null))
				{
					break;
				}
			}
		}

		private static bool GetScriptedRandom(Xoroshiro128Plus rng, List<BuffIndex> currentBuffs, out EliteDef result)
		{
			result = null;
			EliteTierDef[] eliteTiers = CombatDirector.eliteTiers;
			if (eliteTiers == null || eliteTiers.Length == 0)
			{
				return false;
			}
			IEnumerable<EliteDef> source = from etd in eliteTiers
				where etd != null && !etd.canSelectWithoutAvailableEliteDef
				from ed in etd.availableDefs
				where CrueltyManager.IsValid(ed, currentBuffs)
				select ed;
			if (source.Any())
			{
				int index = rng.RangeInt(0, source.Count());
				result = source.ElementAt(index);
				return true;
			}
			return false;
		}
	}
}