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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DirectorRework.Config;
using DirectorRework.Cruelty;
using DirectorRework.Hooks;
using EntityStates;
using HG;
using HarmonyLib;
using IL.EntityStates.VoidInfestor;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
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+acb3c0d519c760ccde2939b37c4d4ce9b6d469dd")]
[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.1.3")]
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.1.3";
public static DirectorReworkPlugin Instance { get; private set; }
public static bool RooInstalled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
public void Awake()
{
Instance = this;
Log.Init(((BaseUnityPlugin)this).Logger);
PluginConfig.Init(((BaseUnityPlugin)this).Config);
CrueltyManager.Init();
DirectorMain.Init();
DirectorTweaks.Init();
}
}
public static class Log
{
private static ManualLogSource _logSource;
internal static void Init(ManualLogSource logSource)
{
_logSource = logSource;
}
public static void Debug(string 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<int> maxScriptedAffixes;
public static ConfigEntry<bool> guaranteeSpecialBoss;
public static ConfigEntry<bool> allowBosses;
public static ConfigEntry<bool> onlyApplyToElites;
public static ConfigEntry<bool> bossesAreElite;
public static ConfigEntry<int> triggerChance;
public static ConfigEntry<int> successChance;
public static ConfigEntry<bool> enableBossDiversity;
public static ConfigEntry<bool> enableSpawnDiversity;
public static ConfigEntry<bool> enableVieldsDiversity;
public static ConfigEntry<bool> enableCreditRefund;
public static ConfigEntry<int> creditRefundMultiplier;
public static ConfigEntry<bool> useRecommendedValues;
public static ConfigEntry<float> minRerollSpawnInterval;
public static ConfigEntry<float> maxRerollSpawnInterval;
public static ConfigEntry<float> creditMultiplier;
public static ConfigEntry<float> eliteBias;
public static ConfigEntry<float> creditMultiplierForEachMountainShrine;
public static ConfigEntry<float> goldAndExperienceMultiplierForEachMountainShrine;
public static ConfigEntry<int> maximumNumberToSpawnBeforeSkipping;
public static ConfigEntry<int> maxConsecutiveCheapSkips;
public static T GetValue<T>(this ConfigEntry<T> entry)
{
if (useRecommendedValues.Value)
{
return (T)((ConfigEntryBase)entry).DefaultValue;
}
return entry.Value;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void Init(ConfigFile cfg)
{
MainConfig = cfg;
if (DirectorReworkPlugin.RooInstalled)
{
InitRoO();
}
string section = "1. Modules";
enableCruelty = cfg.BindOption(section, "Enable Affix Stacking", defaultValue: false, "Enables Affix Stacking (highly inspired by Artifact of Cruelty in RiskyArtifacts). Disable to prevent all modifications in 'Affixes/Cruelty' from loading.");
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.");
enableDirectorTweaks = cfg.BindOption(section, "Enable Combat Director Tweaks", defaultValue: true, "!!! Highly recommend to disable/zero out other mods that modify the combat director. Some options will stack exponentially !!!\r\n\r\nEnables 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.");
section = "2. Affixes/Cruelty";
maxAffixes = cfg.BindOptionSlider(section, "Max Additional Affixes", 3, "Maximum Affixes that an enemy can have. Combat Director will still need to afford the combined credit cost of the new enemy.", 0f, 10f);
maxScriptedAffixes = cfg.BindOptionSlider(section, "Max Scripted Event Affixes", 2, "Maximum Affixes that an enemy from a scripted event (Mithrix, void cradle) can have.", 0f, 10f);
guaranteeSpecialBoss = cfg.BindOption(section, "Guarantee Special Boss", defaultValue: false, "Always apply additional affixes to special bosses in scripted events. Applies to void cradles, Mithrix, Alloy Worship Unit, etc");
allowBosses = cfg.BindOption(section, "Allow Boss Affix Stacking", defaultValue: false, "Allows any bosses to recieve additional affixes. This setting is ignored during scripted combat events if Guarantee Special Boss is true.");
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.");
bossesAreElite = cfg.BindOption(section, "Bosses Ignore Elite Setting", defaultValue: true, "When enabled, bosses do not have to be elite to receive affixes.");
triggerChance = cfg.BindOptionSlider(section, "Trigger Chance", 20, "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", 20, "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);
section = "3. Director Main";
enableBossDiversity = cfg.BindOption(section, "Enable Boss Diversity", defaultValue: true, "Spawns multiple boss types during teleporter events.");
enableSpawnDiversity = cfg.BindOption(section, "Enable Spawn Diversity", defaultValue: true, "Spawns multiple enemy types per wave.");
enableVieldsDiversity = cfg.BindOption(section, "Enable Void Fields Spawn Diversity", defaultValue: false, "Spawns multiple enemy types in void fields. Selection is limited to the enemy types that can spawn on the final wave.");
enableCreditRefund = cfg.BindOption(section, "Enable Credit Refund", defaultValue: false, "Gives combat director back a percent of credits spent on spawns when they are killed.");
creditRefundMultiplier = cfg.BindOptionSlider(section, "Percent Refund", 10, "Amount to refund the combat director when an enemy is killed, in percent. 100 is a bad idea, but its technically possible.", 0f, 100f);
section = "Director Tweaks";
useRecommendedValues = cfg.BindOption(section, "Use Recommended Values", defaultValue: true, "If enabled, then the recommended values for this section will be used instead of the ones set in the config. Disable this setting if you want to change this section.");
creditMultiplier = cfg.BindOptionSlider(section, "Credit Multiplier", 1f, "How much to multiply money wave yield by. Vanilla is 1. \r\n\r\n!!! ITS RECOMMENDED TO SET ALL OTHER MODS TO 1 !!!", 0.1f, 5f);
eliteBias = cfg.BindOptionSlider(section, "Elite Bias Cost Multiplier", 1f, "Multiplies the elite selection cost. Higher numbers result in higher cost and therefore less elites. Vanilla is 1", 0.1f, 5f);
minRerollSpawnInterval = cfg.BindOptionSlider(section, "Minimum Reroll Spawn Interval", 4.3333335f, "Used when a spawn is rejected and the director needs to wait to build more credits. Vanilla is 2.33333", 0.1f);
maxRerollSpawnInterval = cfg.BindOptionSlider(section, "Maximum Reroll Spawn Interval", 6.3333335f, "Used when a spawn is rejected and the director needs to wait to build more credits. Vanilla is 4.33333", 0.1f);
creditMultiplierForEachMountainShrine = cfg.BindOptionSlider(section, "Credit Multiplier For Each Mountain Shrine", 1f, "Credit multiplier for the teleporter director for each mountain shrine", 0.1f, 5f);
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. Vanilla is 1", 0.1f, 5f);
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. Vanilla is 6", 1f);
maxConsecutiveCheapSkips = cfg.BindOptionSlider(section, "Max Consecutive Cheap Skips", 10, "If skipSpawnIfTooCheap is true, we'll behave as though it's not set after this many consecutive skips. Vanilla is -1", -1f);
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void InitRoO()
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
//IL_0063: 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_007c: Expected O, but got Unknown
try
{
ModSettingsManager.SetModDescription("Combat Director Tweaks and Elite Stacking", "com.score.DirectorReworkPlus", "DirectorReworkPlus");
byte[] array = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)DirectorReworkPlugin.Instance).Info.Location), "icon.png"));
Texture2D val = new Texture2D(256, 256);
ImageConversion.LoadImage(val, array);
ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f)));
}
catch (Exception ex)
{
Log.Debug(ex.ToString());
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static ConfigEntry<T> BindOption<T>(this ConfigFile myConfig, string section, string name, T defaultValue, string description = "", bool restartRequired = false)
{
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Expected O, but got Unknown
bool flag = ((defaultValue is int || defaultValue is float) ? true : false);
if (flag && !typeof(T).IsEnum)
{
return myConfig.BindOptionSlider(section, name, defaultValue, description, 0f, 20f, restartRequired);
}
if (string.IsNullOrEmpty(description))
{
description = name;
}
if (restartRequired)
{
description += " (restart required)";
}
AcceptableValueBase val = null;
if (typeof(T).IsEnum)
{
val = (AcceptableValueBase)(object)new AcceptableValueList<string>(Enum.GetNames(typeof(T)));
}
ConfigEntry<T> val2 = myConfig.Bind<T>(section, name, defaultValue, new ConfigDescription(description, val, Array.Empty<object>()));
if (DirectorReworkPlugin.RooInstalled)
{
TryRegisterOption<T>(val2, restartRequired);
}
return val2;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
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)
{
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: Expected O, but got Unknown
bool flag = ((defaultValue is int || defaultValue is float) ? true : false);
if (!flag || typeof(T).IsEnum)
{
return myConfig.BindOption(section, name, defaultValue, description, restartRequired);
}
if (string.IsNullOrEmpty(description))
{
description = name;
}
string text = description;
T val = defaultValue;
description = text + " (Default: " + val?.ToString() + ")";
if (restartRequired)
{
description += " (restart required)";
}
AcceptableValueBase val2 = (AcceptableValueBase)((typeof(T) == typeof(int)) ? ((object)new AcceptableValueRange<int>((int)min, (int)max)) : ((object)new AcceptableValueRange<float>(min, max)));
ConfigEntry<T> val3 = myConfig.Bind<T>(section, name, defaultValue, new ConfigDescription(description, val2, Array.Empty<object>()));
if (DirectorReworkPlugin.RooInstalled)
{
TryRegisterOptionSlider<T>(val3, min, max, restartRequired);
}
return val3;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static ConfigEntry<T> BindOptionSteppedSlider<T>(this ConfigFile myConfig, string section, string name, T defaultValue, float increment = 1f, string description = "", float min = 0f, float max = 20f, bool restartRequired = false)
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
if (string.IsNullOrEmpty(description))
{
description = name;
}
string text = description;
T val = defaultValue;
description = text + " (Default: " + val?.ToString() + ")";
if (restartRequired)
{
description += " (restart required)";
}
ConfigEntry<T> val2 = myConfig.Bind<T>(section, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
if (DirectorReworkPlugin.RooInstalled)
{
TryRegisterOptionSteppedSlider<T>(val2, increment, min, max, restartRequired);
}
return val2;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void TryRegisterOption<T>(ConfigEntry<T> entry, 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_0012: 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_0023: 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_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Expected O, but got Unknown
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Expected O, but got Unknown
if (entry is ConfigEntry<string> val)
{
ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(val, new InputFieldConfig
{
submitOn = (SubmitEnum)6,
restartRequired = restartRequired
}));
}
else if (entry is ConfigEntry<bool> val2)
{
ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(val2, restartRequired));
}
else if (entry is ConfigEntry<KeyboardShortcut> val3)
{
ModSettingsManager.AddOption((BaseOption)new KeyBindOption(val3, restartRequired));
}
else if (typeof(T).IsEnum)
{
ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)entry, restartRequired));
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
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
}));
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static void TryRegisterOptionSteppedSlider<T>(ConfigEntry<T> entry, float increment, 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_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: 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_003d: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
if (entry is ConfigEntry<float> val)
{
ModSettingsManager.AddOption((BaseOption)new StepSliderOption(val, new StepSliderConfig
{
increment = increment,
min = min,
max = max,
FormatString = "{0:0.00}",
restartRequired = restartRequired
}));
}
}
}
}
namespace DirectorRework.Hooks
{
public class CrueltyManager
{
[CompilerGenerated]
private static class <>O
{
public static hook_Awake <0>__CombatDirector_Awake;
public static hook_Awake <1>__ScriptedCombatEncounter_Awake;
public static Manipulator <2>__Infest_FixedUpdate;
public static Manipulator <3>__GlobalEventManager_OnCharacterDeath;
}
private HashSet<EquipmentIndex> BlacklistedElites { get; set; } = new HashSet<EquipmentIndex>();
public static CrueltyManager Instance { get; private set; }
public bool HooksEnabled { get; set; }
public static void Init()
{
if (Instance == null)
{
Instance = new CrueltyManager();
}
}
private CrueltyManager()
{
RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnLoad));
PluginConfig.enableCruelty.SettingChanged += OnSettingChanged;
OnSettingChanged(null, null);
}
public void OnSettingChanged(object sender, EventArgs args)
{
if (PluginConfig.enableCruelty.Value)
{
SetHooks();
}
else
{
UnsetHooks();
}
}
public void SetHooks()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_008c: 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_0097: Expected O, but got Unknown
if (!HooksEnabled)
{
GlobalEventManager.onCharacterDeathGlobal += GlobalEventManager_onCharacterDeathGlobal;
object obj = <>O.<0>__CombatDirector_Awake;
if (obj == null)
{
hook_Awake val = CombatCruelty.CombatDirector_Awake;
<>O.<0>__CombatDirector_Awake = val;
obj = (object)val;
}
CombatDirector.Awake += (hook_Awake)obj;
object obj2 = <>O.<1>__ScriptedCombatEncounter_Awake;
if (obj2 == null)
{
hook_Awake val2 = ScriptedCruelty.ScriptedCombatEncounter_Awake;
<>O.<1>__ScriptedCombatEncounter_Awake = val2;
obj2 = (object)val2;
}
ScriptedCombatEncounter.Awake += (hook_Awake)obj2;
object obj3 = <>O.<2>__Infest_FixedUpdate;
if (obj3 == null)
{
Manipulator val3 = Infest_FixedUpdate;
<>O.<2>__Infest_FixedUpdate = val3;
obj3 = (object)val3;
}
Infest.FixedUpdate += (Manipulator)obj3;
object obj4 = <>O.<3>__GlobalEventManager_OnCharacterDeath;
if (obj4 == null)
{
Manipulator val4 = GlobalEventManager_OnCharacterDeath;
<>O.<3>__GlobalEventManager_OnCharacterDeath = val4;
obj4 = (object)val4;
}
GlobalEventManager.OnCharacterDeath += (Manipulator)obj4;
HooksEnabled = true;
}
}
public void UnsetHooks()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_008c: 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_0097: Expected O, but got Unknown
if (HooksEnabled)
{
GlobalEventManager.onCharacterDeathGlobal -= GlobalEventManager_onCharacterDeathGlobal;
object obj = <>O.<0>__CombatDirector_Awake;
if (obj == null)
{
hook_Awake val = CombatCruelty.CombatDirector_Awake;
<>O.<0>__CombatDirector_Awake = val;
obj = (object)val;
}
CombatDirector.Awake -= (hook_Awake)obj;
object obj2 = <>O.<1>__ScriptedCombatEncounter_Awake;
if (obj2 == null)
{
hook_Awake val2 = ScriptedCruelty.ScriptedCombatEncounter_Awake;
<>O.<1>__ScriptedCombatEncounter_Awake = val2;
obj2 = (object)val2;
}
ScriptedCombatEncounter.Awake -= (hook_Awake)obj2;
object obj3 = <>O.<2>__Infest_FixedUpdate;
if (obj3 == null)
{
Manipulator val3 = Infest_FixedUpdate;
<>O.<2>__Infest_FixedUpdate = val3;
obj3 = (object)val3;
}
Infest.FixedUpdate -= (Manipulator)obj3;
object obj4 = <>O.<3>__GlobalEventManager_OnCharacterDeath;
if (obj4 == null)
{
Manipulator val4 = GlobalEventManager_OnCharacterDeath;
<>O.<3>__GlobalEventManager_OnCharacterDeath = val4;
obj4 = (object)val4;
}
GlobalEventManager.OnCharacterDeath -= (Manipulator)obj4;
HooksEnabled = false;
}
}
private 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_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Invalid comparison between Unknown and I4
//IL_000f: 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_0043: 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)
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);
}
}
}
private void GlobalEventManager_onCharacterDeathGlobal(DamageReport report)
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ea: 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_0106: 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)
//IL_011a: Unknown result type (might be due to invalid IL or missing references)
//IL_011f: Unknown result type (might be due to invalid IL or missing references)
//IL_012d: 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_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
//IL_0156: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0162: Unknown result type (might be due to invalid IL or missing references)
//IL_0169: Unknown result type (might be due to invalid IL or missing references)
if (!NetworkServer.active || !report.victimIsElite || !Object.op_Implicit((Object)(object)report.victimBody))
{
return;
}
Inventory val = (Object.op_Implicit((Object)(object)report.victimMaster) ? report.victimMaster.inventory : null);
if (!Object.op_Implicit((Object)(object)val) || val.GetEquipmentSlotCount() <= 1)
{
return;
}
float num = (Object.op_Implicit((Object)(object)report.attackerMaster) ? report.attackerMaster.luck : 0f);
for (uint num2 = 1u; num2 < val.GetEquipmentSlotCount(); num2++)
{
EquipmentDef equipmentDef = val.GetEquipment(num2).equipmentDef;
if (Object.op_Implicit((Object)(object)equipmentDef) && Util.CheckRoll(equipmentDef.dropOnDeathChance * 100f, num + (float)num2, report.attackerMaster))
{
Ray val2 = (Ray)(Object.op_Implicit((Object)(object)report.victimBody.inputBank) ? report.victimBody.inputBank.GetAimRay() : new Ray(report.victimBody.corePosition, report.victimBody.transform.rotation * Vector3.forward));
((Ray)(ref val2)).origin = ((Ray)(ref val2)).origin + Vector3.up * 1.5f;
((Ray)(ref val2)).direction = ((Ray)(ref val2)).direction * 2f + Vector3.up * 20f;
PickupDropletController.CreatePickupDroplet(PickupCatalog.FindPickupIndex(equipmentDef.equipmentIndex), ((Ray)(ref val2)).origin, ((Ray)(ref val2)).direction);
}
}
}
private static void GlobalEventManager_OnCharacterDeath(ILContext il)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
ILCursor val = new ILCursor(il);
int victimBodyLoc = 0;
int infestorMasterLoc = 0;
if (val.TryGotoNext(new Func<Instruction, bool>[3]
{
(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref victimBodyLoc),
(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, AccessTools.Field(typeof(Buffs), "EliteVoid")),
(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.Method(typeof(CharacterBody), "HasBuff", new Type[1] { typeof(BuffDef) }, (Type[])null))
}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
{
(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref infestorMasterLoc),
(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CharacterMaster>(x, "SpawnBodyHere")
}))
{
val.Emit(OpCodes.Ldloc, victimBodyLoc);
val.Emit(OpCodes.Ldloc, infestorMasterLoc);
val.Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(CrueltyManager), "TransferAffixes", new Type[2]
{
typeof(CharacterBody),
typeof(CharacterMaster)
}, (Type[])null));
}
else
{
Log.Error("Director Rework: GlobalEventManager_OnCharacterDeath IL Hook failed");
}
}
private static void Infest_FixedUpdate(ILContext il)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Expected O, but got Unknown
//IL_008b: 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_00b7: 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)
ILCursor val = new ILCursor(il);
int loc = 0;
if (val.TryGotoNext(new Func<Instruction, bool>[2]
{
(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref loc),
(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.PropertyGetter(typeof(CharacterBody), "inventory"))
}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
{
(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "SetEquipmentIndex")
}))
{
val.Emit(OpCodes.Ldarg_0);
val.Emit(OpCodes.Call, (MethodBase)AccessTools.PropertyGetter(typeof(EntityState), "characterBody"));
val.Emit(OpCodes.Ldloc, loc);
val.Emit(OpCodes.Call, (MethodBase)AccessTools.Method(typeof(CrueltyManager), "TransferAffixes", new Type[2]
{
typeof(CharacterBody),
typeof(CharacterBody)
}, (Type[])null));
}
else
{
Log.Error("Director Rework: Infest_FixedUpdate IL Hook failed");
}
}
internal static void TransferAffixes(CharacterBody sourceBody, CharacterMaster targetMaster)
{
TransferAffixes(Object.op_Implicit((Object)(object)sourceBody) ? sourceBody.inventory : null, Object.op_Implicit((Object)(object)targetMaster) ? targetMaster.GetBody() : null);
}
internal static void TransferAffixes(CharacterBody sourceBody, CharacterBody targetBody)
{
TransferAffixes(Object.op_Implicit((Object)(object)sourceBody) ? sourceBody.inventory : null, targetBody);
}
internal static void TransferAffixes(Inventory source, CharacterBody targetBody)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Invalid comparison between Unknown and I4
//IL_0056: 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_0073: Invalid comparison between Unknown and I4
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
Inventory val = (Object.op_Implicit((Object)(object)targetBody) ? targetBody.inventory : null);
if (!Object.op_Implicit((Object)(object)source) || !Object.op_Implicit((Object)(object)val))
{
return;
}
uint num = 0u;
for (uint num2 = 0u; num2 <= val.GetEquipmentSlotCount(); num2++)
{
if ((int)val.GetEquipment(num2).equipmentIndex == -1)
{
num = num2;
break;
}
}
for (uint num3 = 0u; num3 < source.GetEquipmentSlotCount(); num3++)
{
EquipmentDef equipmentDef = source.GetEquipment(num3).equipmentDef;
if (Object.op_Implicit((Object)(object)equipmentDef) && (int)equipmentDef.equipmentIndex != -1 && Object.op_Implicit((Object)(object)equipmentDef.passiveBuffDef) && equipmentDef.passiveBuffDef.isElite)
{
val.SetEquipmentIndexForSlot(equipmentDef.equipmentIndex, num);
targetBody.AddBuff(equipmentDef.passiveBuffDef);
num++;
}
}
}
internal static void GiveAffix(CharacterBody body, Inventory inventory, EquipmentDef equipment)
{
//IL_0006: 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_0011: Invalid comparison between Unknown and I4
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
for (uint num = 0u; num <= inventory.GetEquipmentSlotCount(); num++)
{
if ((int)inventory.GetEquipment(num).equipmentIndex == -1)
{
inventory.SetEquipmentIndexForSlot(equipment.equipmentIndex, num);
break;
}
}
body.SetBuffCount(equipment.passiveBuffDef.buffIndex, 1);
}
internal static void GiveItemBoosts(Inventory inventory, EliteDef def, int affixes)
{
inventory.GiveItem(Items.BoostHp, Mathf.RoundToInt(def.healthBoostCoefficient * 10f / (float)(affixes + 2)));
inventory.GiveItem(Items.BoostDamage, Mathf.RoundToInt((def.damageBoostCoefficient - 1f) * 10f / (float)(affixes + 1)));
}
internal static void GiveDeathReward(DeathRewards deathReward, uint xp, uint gold, int affixes)
{
if (Object.op_Implicit((Object)(object)deathReward))
{
if (xp != 0)
{
deathReward.expReward += Convert.ToUInt32(xp / affixes);
}
if (gold != 0)
{
deathReward.goldReward += Convert.ToUInt32(gold / affixes);
}
}
}
internal static bool IsValid(EliteDef ed, List<BuffIndex> currentBuffs)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
if (Object.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 && !Instance.BlacklistedElites.Contains(ed.eliteEquipmentDef.equipmentIndex))
{
return !currentBuffs.Contains(ed.eliteEquipmentDef.passiveBuffDef.buffIndex);
}
return false;
}
}
internal class DirectorMain
{
[CompilerGenerated]
private static class <>O
{
public static Manipulator <0>__CombatDirector_AttemptSpawnOnTarget;
public static Action<CombatDirector> <1>__Simulate;
}
private const string SUBTITLE_FORMAT = "<sprite name=\"CloudLeft\" tint=1> {0} <sprite name=\"CloudRight\" tint=1>";
public bool HooksEnabled { get; set; }
public bool RefundEnabled { get; set; }
public static bool VarietyEnabled
{
get
{
if (!PluginConfig.enableSpawnDiversity.Value && !PluginConfig.enableVieldsDiversity.Value)
{
return PluginConfig.enableBossDiversity.Value;
}
return true;
}
}
public static DirectorMain Instance { get; private set; }
public static void Init()
{
if (Instance == null)
{
Instance = new DirectorMain();
}
}
private DirectorMain()
{
OnSettingChanged(null, null);
PluginConfig.enableDirectorMain.SettingChanged += OnSettingChanged;
PluginConfig.enableSpawnDiversity.SettingChanged += OnSettingChanged;
PluginConfig.enableCreditRefund.SettingChanged += OnSettingChanged;
}
public void OnSettingChanged(object sender, EventArgs a)
{
if (PluginConfig.enableDirectorMain.Value)
{
SetHooks();
}
else
{
UnsetHooks();
}
}
public void SetHooks()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00ab: Expected O, but got Unknown
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Expected O, but got Unknown
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Expected O, but got Unknown
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Expected O, but got Unknown
if (!RefundEnabled && PluginConfig.enableCreditRefund.Value)
{
CombatDirector.Awake += new hook_Awake(CombatDirector_Awake);
RefundEnabled = true;
}
else if (RefundEnabled && !PluginConfig.enableCreditRefund.Value)
{
CombatDirector.Awake -= new hook_Awake(CombatDirector_Awake);
RefundEnabled = false;
}
if (!HooksEnabled && VarietyEnabled)
{
object obj = <>O.<0>__CombatDirector_AttemptSpawnOnTarget;
if (obj == null)
{
Manipulator val = CombatDirector_AttemptSpawnOnTarget;
<>O.<0>__CombatDirector_AttemptSpawnOnTarget = val;
obj = (object)val;
}
CombatDirector.AttemptSpawnOnTarget += (Manipulator)obj;
Chat.SendBroadcastChat_ChatMessageBase += new hook_SendBroadcastChat_ChatMessageBase(ChangeMessage);
BossGroup.UpdateBossMemories += new hook_UpdateBossMemories(UpdateTitle);
HooksEnabled = true;
}
else if (HooksEnabled && !VarietyEnabled)
{
object obj2 = <>O.<0>__CombatDirector_AttemptSpawnOnTarget;
if (obj2 == null)
{
Manipulator val2 = CombatDirector_AttemptSpawnOnTarget;
<>O.<0>__CombatDirector_AttemptSpawnOnTarget = val2;
obj2 = (object)val2;
}
CombatDirector.Simulate -= (Manipulator)obj2;
Chat.SendBroadcastChat_ChatMessageBase -= new hook_SendBroadcastChat_ChatMessageBase(ChangeMessage);
BossGroup.UpdateBossMemories -= new hook_UpdateBossMemories(UpdateTitle);
HooksEnabled = false;
}
}
public void UnsetHooks()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Expected O, but got Unknown
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
if (RefundEnabled)
{
CombatDirector.Awake -= new hook_Awake(CombatDirector_Awake);
RefundEnabled = false;
}
if (HooksEnabled)
{
object obj = <>O.<0>__CombatDirector_AttemptSpawnOnTarget;
if (obj == null)
{
Manipulator val = CombatDirector_AttemptSpawnOnTarget;
<>O.<0>__CombatDirector_AttemptSpawnOnTarget = val;
obj = (object)val;
}
CombatDirector.AttemptSpawnOnTarget -= (Manipulator)obj;
Chat.SendBroadcastChat_ChatMessageBase -= new hook_SendBroadcastChat_ChatMessageBase(ChangeMessage);
BossGroup.UpdateBossMemories -= new hook_UpdateBossMemories(UpdateTitle);
HooksEnabled = false;
}
}
private static void CombatDirector_AttemptSpawnOnTarget(ILContext il)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
ILCursor val = new ILCursor(il)
{
Index = il.Instrs.Count - 1
};
if (val.TryGotoPrev(new Func<Instruction, bool>[2]
{
(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 1),
(Instruction x) => ILPatternMatchingExt.MatchRet(x)
}))
{
val.Emit(OpCodes.Ldarg_0);
val.EmitDelegate<Action<CombatDirector>>((Action<CombatDirector>)Simulate);
}
else
{
Log.Error("IL Hook failed for CombatDirector.Simulate");
}
}
public static void Simulate(CombatDirector self)
{
if (!VarietyEnabled)
{
return;
}
ArenaMissionController instance = ArenaMissionController.instance;
if (instance != null && (instance.activeMonsterCards?.Any()).GetValueOrDefault())
{
if (PluginConfig.enableVieldsDiversity.Value)
{
self.PrepareNewMonsterWave(self.rng.NextElementUniform<DirectorCard>(ArenaMissionController.instance.activeMonsterCards));
}
return;
}
WeightedSelection<DirectorCard> finalMonsterCardsSelection = self.finalMonsterCardsSelection;
if (finalMonsterCardsSelection == null || finalMonsterCardsSelection.Count <= 0)
{
return;
}
if ((Object)(object)self == (Object)(object)TeleporterInteraction.instance?.bossDirector)
{
if (PluginConfig.enableBossDiversity.Value)
{
SetNextSpawn(self, isBoss: true);
}
}
else if (self.spawnCountInCurrentWave < self.maximumNumberToSpawnBeforeSkipping && PluginConfig.enableSpawnDiversity.Value)
{
SetNextSpawn(self, isBoss: false);
}
}
private static void SetNextSpawn(CombatDirector self, bool isBoss)
{
//IL_0054: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
int mostExpensiveMonsterCostInDeck = self.mostExpensiveMonsterCostInDeck;
bool flag = isBoss && self.currentMonsterCard.spawnCard.prefab.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<CharacterBody>().isChampion;
WeightedSelection<DirectorCard> val = new WeightedSelection<DirectorCard>(8);
int i = 0;
for (int count = self.finalMonsterCardsSelection.Count; i < count; i++)
{
ChoiceInfo<DirectorCard> choice = self.finalMonsterCardsSelection.GetChoice(i);
if (!choice.value.IsAvailable() || !((float)choice.value.cost <= self.monsterCredit))
{
continue;
}
if (isBoss)
{
SpawnCard spawnCard = choice.value.spawnCard;
bool isChampion = spawnCard.prefab.GetComponent<CharacterMaster>().bodyPrefab.GetComponent<CharacterBody>().isChampion;
bool flag2 = ((CharacterSpawnCard)(((spawnCard is CharacterSpawnCard) ? spawnCard : null)?)).forbiddenAsBoss ?? false;
if (isChampion == flag && !flag2 && ValidateBossCard(self, choice.value, mostExpensiveMonsterCostInDeck))
{
val.AddChoice(choice);
}
}
else
{
val.AddChoice(choice);
}
}
if (val.Count > 0)
{
self.currentMonsterCard = val.Evaluate(self.rng.nextNormalizedFloat);
self.currentActiveEliteTier = GetBestEliteTier(self, self.currentMonsterCard);
self.currentActiveEliteDef = self.currentActiveEliteTier.GetRandomAvailableEliteDef(self.rng);
self.lastAttemptedMonsterCard = self.currentMonsterCard;
}
}
private static bool ValidateBossCard(CombatDirector self, DirectorCard spawnCard, int mostExpensive)
{
float costMultiplier = GetBestEliteTier(self, spawnCard).costMultiplier;
int num = spawnCard.cost;
int num2 = (int)((float)num * costMultiplier);
if ((float)num2 <= self.monsterCredit)
{
num = num2;
}
if (self.skipSpawnIfTooCheap && (float)(num * self.maximumNumberToSpawnBeforeSkipping) < self.monsterCredit && mostExpensive > num)
{
return false;
}
return true;
}
private static EliteTierDef GetBestEliteTier(CombatDirector self, DirectorCard currentMonsterCard)
{
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
EliteTierDef result = CombatDirector.eliteTiers[0];
for (int i = 0; i < CombatDirector.eliteTiers.Length; i++)
{
if (CombatDirector.eliteTiers[i].CanSelect(currentMonsterCard.spawnCard.eliteRules))
{
result = CombatDirector.eliteTiers[i];
break;
}
}
SpawnCard spawnCard = currentMonsterCard.spawnCard;
if (!((CharacterSpawnCard)((spawnCard is CharacterSpawnCard) ? spawnCard : null)).noElites)
{
for (int j = 1; j < CombatDirector.eliteTiers.Length; j++)
{
EliteTierDef val = CombatDirector.eliteTiers[j];
if (val.CanSelect(currentMonsterCard.spawnCard.eliteRules) && (float)currentMonsterCard.cost * val.costMultiplier * self.eliteBias <= self.monsterCredit)
{
result = val;
}
}
}
return result;
}
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.enableBossDiversity.Value)
{
return;
}
float num = float.MinValue;
CharacterBody val = null;
for (int i = 0; i < self.bossMemoryCount; i++)
{
ref BossMemory reference = ref self.bossMemories[i];
if (Object.op_Implicit((Object)(object)reference.cachedBody) && !(reference.lastObservedHealth <= 0f))
{
float num2 = reference.maxObservedMaxHealth + 4f * Mathf.Max(0f, reference.maxObservedMaxHealth - reference.lastObservedHealth);
if (num2 > num)
{
num = num2;
val = reference.cachedBody;
}
}
}
if (Object.op_Implicit((Object)(object)val))
{
self.bestObservedName = Util.GetBestBodyName(((Component)val).gameObject);
string text = val.GetSubtitle();
if (string.IsNullOrEmpty(text))
{
text = Language.GetString("NULL_SUBTITLE");
}
self.bestObservedSubtitle = $"<sprite name=\"CloudLeft\" tint=1> {text} <sprite name=\"CloudRight\" tint=1>";
}
}
private void CombatDirector_Awake(orig_Awake orig, CombatDirector self)
{
orig.Invoke(self);
if (NetworkServer.active && !((Object)(object)self == (Object)(object)TeleporterInteraction.instance?.bossDirector))
{
((UnityEvent<GameObject>)(object)self.onSpawnedServer).AddListener((UnityAction<GameObject>)OnSpawnedServer);
}
void OnBodyDestroyed(CharacterBody body)
{
if (PluginConfig.creditRefundMultiplier.Value > 0 && Object.op_Implicit((Object)(object)self) && ((Behaviour)self).isActiveAndEnabled && self.monsterCredit > 0f)
{
float? num = body?.cost * (float)PluginConfig.creditRefundMultiplier.Value * 0.01f;
if (num.HasValue)
{
CombatDirector obj = self;
obj.monsterCredit += num.Value;
}
}
}
void OnSpawnedServer(GameObject masterObject)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Invalid comparison between Unknown and I4
CharacterMaster val = (Object.op_Implicit((Object)(object)masterObject) ? masterObject.GetComponent<CharacterMaster>() : null);
if (Object.op_Implicit((Object)(object)val))
{
CharacterBody body2 = val.GetBody();
if (Object.op_Implicit((Object)(object)body2) && !body2.isBoss && !body2.isChampion && body2.cost > 0f && (int)body2.teamComponent.teamIndex == 2)
{
val.onBodyDestroyed += OnBodyDestroyed;
}
}
}
}
}
internal class DirectorTweaks
{
private float prevCreditMult = PluginConfig.creditMultiplier.GetValue<float>();
private float prevEliteBias = PluginConfig.eliteBias.GetValue<float>();
public static DirectorTweaks instance;
public bool HooksEnabled { get; set; }
public static void Init()
{
if (instance == null)
{
instance = new DirectorTweaks();
}
}
private DirectorTweaks()
{
OnSettingChanged(null, null);
PluginConfig.enableDirectorTweaks.SettingChanged += OnSettingChanged;
PluginConfig.useRecommendedValues.SettingChanged += OnSettingValuesChanged;
PluginConfig.minRerollSpawnInterval.SettingChanged += OnSettingValuesChanged;
PluginConfig.maxRerollSpawnInterval.SettingChanged += OnSettingValuesChanged;
PluginConfig.maxConsecutiveCheapSkips.SettingChanged += OnSettingValuesChanged;
PluginConfig.maximumNumberToSpawnBeforeSkipping.SettingChanged += OnSettingValuesChanged;
PluginConfig.creditMultiplierForEachMountainShrine.SettingChanged += OnSettingValuesChanged;
PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.SettingChanged += OnSettingValuesChanged;
PluginConfig.creditMultiplier.SettingChanged += OnSettingValuesChanged;
PluginConfig.eliteBias.SettingChanged += OnSettingValuesChanged;
}
public void OnSettingChanged(object sender, EventArgs args)
{
if (PluginConfig.enableDirectorTweaks.Value)
{
SetHooks();
}
else
{
UnsetHooks();
}
}
public void SetHooks()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (!HooksEnabled)
{
CombatDirector.Awake += new hook_Awake(CombatDirector_Awake);
ChargingState.OnEnter += new hook_OnEnter(ChargingState_OnEnter);
HooksEnabled = true;
}
}
public void UnsetHooks()
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Expected O, but got Unknown
if (HooksEnabled)
{
CombatDirector.Awake -= new hook_Awake(CombatDirector_Awake);
ChargingState.OnEnter -= new hook_OnEnter(ChargingState_OnEnter);
HooksEnabled = false;
}
}
public void OnSettingValuesChanged(object sender, EventArgs args)
{
if (!HooksEnabled)
{
return;
}
foreach (CombatDirector instances in CombatDirector.instancesList)
{
instances.maxConsecutiveCheapSkips = ((PluginConfig.maxConsecutiveCheapSkips.GetValue<int>() <= 0) ? int.MaxValue : PluginConfig.maxConsecutiveCheapSkips.GetValue<int>());
instances.maximumNumberToSpawnBeforeSkipping = PluginConfig.maximumNumberToSpawnBeforeSkipping.GetValue<int>();
instances.minRerollSpawnInterval = PluginConfig.minRerollSpawnInterval.GetValue<float>();
instances.maxRerollSpawnInterval = PluginConfig.maxRerollSpawnInterval.GetValue<float>();
instances.creditMultiplier /= prevCreditMult;
instances.creditMultiplier *= PluginConfig.creditMultiplier.GetValue<float>();
prevCreditMult = PluginConfig.creditMultiplier.GetValue<float>();
instances.eliteBias /= prevEliteBias;
instances.eliteBias *= PluginConfig.eliteBias.GetValue<float>();
prevEliteBias = PluginConfig.eliteBias.GetValue<float>();
}
}
private void CombatDirector_Awake(orig_Awake orig, CombatDirector self)
{
self.creditMultiplier *= PluginConfig.creditMultiplier.GetValue<float>();
self.eliteBias *= PluginConfig.eliteBias.GetValue<float>();
self.maxConsecutiveCheapSkips = ((PluginConfig.maxConsecutiveCheapSkips.GetValue<int>() <= 0) ? int.MaxValue : PluginConfig.maxConsecutiveCheapSkips.GetValue<int>());
self.maximumNumberToSpawnBeforeSkipping = PluginConfig.maximumNumberToSpawnBeforeSkipping.GetValue<int>();
self.minRerollSpawnInterval = PluginConfig.minRerollSpawnInterval.GetValue<float>();
self.maxRerollSpawnInterval = PluginConfig.maxRerollSpawnInterval.GetValue<float>();
orig.Invoke(self);
}
private void ChargingState_OnEnter(orig_OnEnter orig, BaseState self)
{
ChargingState val = (ChargingState)(object)((self is ChargingState) ? self : null);
if (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 += bossDirector.creditMultiplier * (1f - (float)shrineBonusStacks * PluginConfig.creditMultiplierForEachMountainShrine.GetValue<float>());
CombatDirector obj2 = bossDirector;
obj2.expRewardCoefficient += bossDirector.expRewardCoefficient * (1f - (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.GetValue<float>());
CombatDirector obj3 = bossDirector;
obj3.goldRewardCoefficient += bossDirector.goldRewardCoefficient * (1f - (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.GetValue<float>());
}
bossDirector = val.bonusDirector;
if (Object.op_Implicit((Object)(object)bossDirector))
{
CombatDirector obj4 = bossDirector;
obj4.creditMultiplier += bossDirector.creditMultiplier * (1f - (float)shrineBonusStacks * PluginConfig.creditMultiplierForEachMountainShrine.GetValue<float>());
CombatDirector obj5 = bossDirector;
obj5.expRewardCoefficient += bossDirector.expRewardCoefficient * (1f - (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.GetValue<float>());
CombatDirector obj6 = bossDirector;
obj6.goldRewardCoefficient += bossDirector.goldRewardCoefficient * (1f - (float)shrineBonusStacks * PluginConfig.goldAndExperienceMultiplierForEachMountainShrine.GetValue<float>());
}
}
}
orig.Invoke(self);
}
}
}
namespace DirectorRework.Cruelty
{
public static class CombatCruelty
{
public readonly struct EliteWithCost
{
public readonly EliteDef eliteDef;
public readonly float cost;
public EliteWithCost(EliteDef def, float cost)
{
eliteDef = def;
this.cost = cost;
}
}
public static void CombatDirector_Awake(orig_Awake orig, CombatDirector self)
{
orig.Invoke(self);
if (!NetworkServer.active)
{
return;
}
((UnityEvent<GameObject>)(object)self.onSpawnedServer).AddListener((UnityAction<GameObject>)delegate(GameObject masterObject)
{
if (PluginConfig.enableCruelty.Value && Util.CheckRoll((float)PluginConfig.triggerChance.Value, 0f, (CharacterMaster)null))
{
CharacterMaster val = (Object.op_Implicit((Object)(object)masterObject) ? masterObject.GetComponent<CharacterMaster>() : null);
if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.inventory) && val.inventory.GetItemCount(Items.HealthDecay) <= 0)
{
CharacterBody body = val.GetBody();
if (Object.op_Implicit((Object)(object)body))
{
bool flag = val.isBoss || body.isChampion;
if (!(!PluginConfig.allowBosses.Value && flag))
{
bool flag2 = body.eliteBuffCount > 0 || (PluginConfig.bossesAreElite.Value && flag);
if (!PluginConfig.onlyApplyToElites.Value || flag2)
{
OnSpawnedServer(self, body, val.inventory);
}
}
}
}
}
});
}
private static void OnSpawnedServer(CombatDirector director, CharacterBody body, Inventory inventory)
{
//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)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
List<BuffIndex> list = CollectionPool<BuffIndex, List<BuffIndex>>.RentCollection();
BuffIndex[] eliteBuffIndices = BuffCatalog.eliteBuffIndices;
foreach (BuffIndex val in eliteBuffIndices)
{
if (body.HasBuff(val) && !list.Contains(val))
{
list.Add(val);
}
}
uint xp = 0u;
uint gold = 0u;
DeathRewards val2 = default(DeathRewards);
if (((Component)body).TryGetComponent<DeathRewards>(ref val2))
{
xp = val2.expReward;
gold = val2.goldReward;
}
EliteWithCost result;
while (director.monsterCredit > 0f && list.Count < PluginConfig.maxAffixes.Value && GetRandom(director.monsterCredit, director.currentMonsterCard, director.rng, list, out result))
{
CrueltyManager.GiveAffix(body, inventory, result.eliteDef.eliteEquipmentDef);
list.Add(result.eliteDef.eliteEquipmentDef.passiveBuffDef.buffIndex);
int count = list.Count;
director.monsterCredit -= result.cost;
body.cost += result.cost;
CrueltyManager.GiveItemBoosts(inventory, result.eliteDef, count);
CrueltyManager.GiveDeathReward(val2, xp, gold, count);
if (!Util.CheckRoll((float)PluginConfig.successChance.Value, 0f, (CharacterMaster)null))
{
break;
}
}
CollectionPool<BuffIndex, List<BuffIndex>>.ReturnCollection(list);
}
private static bool GetRandom(float availableCredits, DirectorCard card, Xoroshiro128Plus rng, List<BuffIndex> currentBuffs, out EliteWithCost result)
{
result = default(EliteWithCost);
EliteTierDef[] eliteTiers = CombatDirector.eliteTiers;
if (eliteTiers == null || eliteTiers.Length == 0)
{
return false;
}
DirectorCard obj = card;
int cost = ((obj != null) ? obj.cost : 0) / (currentBuffs.Count + 1);
IEnumerable<EliteWithCost> source = from etd in eliteTiers
where IsValid(etd, card, cost, availableCredits)
from ed in etd.eliteTypes
where CrueltyManager.IsValid(ed, currentBuffs)
select new EliteWithCost(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)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
if (etd != null && !etd.canSelectWithoutAvailableEliteDef && (!Object.op_Implicit((Object)(object)card?.spawnCard) || etd.CanSelect(card.spawnCard.eliteRules)))
{
return availableCredits >= (float)cost * etd.costMultiplier;
}
return false;
}
}
public static class ScriptedCruelty
{
public static void ScriptedCombatEncounter_Awake(orig_Awake orig, ScriptedCombatEncounter self)
{
orig.Invoke(self);
if (!NetworkServer.active || !Object.op_Implicit((Object)(object)self.combatSquad))
{
return;
}
Xoroshiro128Plus rng = self.rng;
self.combatSquad.onMemberAddedServer += delegate(CharacterMaster master)
{
if (PluginConfig.enableCruelty.Value && Object.op_Implicit((Object)(object)master) && Object.op_Implicit((Object)(object)master.inventory) && master.inventory.GetItemCount(Items.HealthDecay) <= 0)
{
CharacterBody body = master.GetBody();
if (Object.op_Implicit((Object)(object)body))
{
if (!PluginConfig.guaranteeSpecialBoss.Value)
{
if (!Util.CheckRoll((float)PluginConfig.triggerChance.Value, 0f, (CharacterMaster)null))
{
return;
}
bool flag = master.isBoss || body.isChampion;
if (!PluginConfig.allowBosses.Value && flag)
{
return;
}
}
OnMemberAddedServer(body, master.inventory, rng);
}
}
};
}
public static void OnMemberAddedServer(CharacterBody body, Inventory inventory, Xoroshiro128Plus rng)
{
//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)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
List<BuffIndex> list = CollectionPool<BuffIndex, List<BuffIndex>>.RentCollection();
BuffIndex[] eliteBuffIndices = BuffCatalog.eliteBuffIndices;
foreach (BuffIndex val in eliteBuffIndices)
{
if (body.HasBuff(val) && !list.Contains(val))
{
list.Add(val);
}
}
uint xp = 0u;
uint gold = 0u;
DeathRewards val2 = default(DeathRewards);
if (((Component)body).TryGetComponent<DeathRewards>(ref val2))
{
xp = val2.expReward;
gold = val2.goldReward;
}
EliteDef result;
while (list.Count < PluginConfig.maxScriptedAffixes.Value && GetScriptedRandom(rng, list, out result))
{
CrueltyManager.GiveAffix(body, inventory, result.eliteEquipmentDef);
list.Add(result.eliteEquipmentDef.passiveBuffDef.buffIndex);
int count = list.Count;
CrueltyManager.GiveItemBoosts(inventory, result, count);
CrueltyManager.GiveDeathReward(val2, xp, gold, count);
if (!Util.CheckRoll((float)PluginConfig.successChance.Value, 0f, (CharacterMaster)null))
{
break;
}
}
CollectionPool<BuffIndex, List<BuffIndex>>.ReturnCollection(list);
}
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.eliteTypes
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;
}
}
}