using System; using System.Collections; 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.Logging; using HG; using HG.Reflection; using IL.RoR2; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using R2API.AddressReferencedAssets; using R2API.AutoVersionGen; using R2API.SpawnCardCloning; using R2API.Utils; using RoR2; using RoR2.ExpansionManagement; using RoR2.Navigation; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("R2API.Director")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.1.0.0")] [assembly: AssemblyInformationalVersion("3.1.0+f539511eabf87f02afddb5a83cafd2f4704c85ad")] [assembly: AssemblyProduct("R2API.Director")] [assembly: AssemblyTitle("R2API.Director")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] [DebuggerNonUserCode] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } } namespace R2API { [CreateAssetMenu(fileName = "New AddressableDCCSPool", menuName = "R2API/DirectorAPI/AddressableDCCSPool")] public class AddressableDCCSPool : ScriptableObject { [Serializable] public class PoolEntry { [Tooltip("The DCCS for this pool entry")] public AddressableDirectorCardCategorySelection dccs; [Tooltip("An address or a Direct reference to an existing Family Director Card Category Selection")] public AddressReferencedFamilyDirectorCardCategorySelection familyDccs; [Tooltip("The weight of this pool entry relative to the others")] public float weight; internal virtual PoolEntry Upgrade() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown return new PoolEntry { dccs = GetDirectorCardCategorySelection(), weight = weight }; } protected DirectorCardCategorySelection GetDirectorCardCategorySelection() { FamilyDirectorCardCategorySelection asset = ((AddressReferencedAsset)(object)familyDccs).Asset; if (Object.op_Implicit((Object)(object)asset)) { return (DirectorCardCategorySelection)(object)asset; } return dccs.targetCardCategorySelection; } } [Serializable] public class ConditionalPoolEntry : PoolEntry { [Tooltip("ALL expansions in this list must be enabled for this run for this entry to be considered")] public AddressReferencedExpansionDef[] requiredExpansions = Array.Empty(); internal override PoolEntry Upgrade() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown ConditionalPoolEntry val = new ConditionalPoolEntry { dccs = GetDirectorCardCategorySelection(), weight = weight }; List list = new List(); AddressReferencedExpansionDef[] array = requiredExpansions; for (int i = 0; i < array.Length; i++) { ExpansionDef asset = ((AddressReferencedAsset)(object)array[i]).Asset; if (Object.op_Implicit((Object)(object)asset)) { list.Add(asset); } } val.requiredExpansions = list.ToArray(); return (PoolEntry)(object)val; } } [Serializable] public class Category { [Tooltip("A name to help identify this category")] public string name; [Tooltip("The weight of all entries in this category relative to the sibling categories")] public float categoryWeight; [Tooltip("These entries are always considered")] public PoolEntry[] alwaysIncluded = Array.Empty(); [Tooltip("These entries are only considered if their individual conditions are met")] public ConditionalPoolEntry[] includedIfConditionsMet = Array.Empty(); [Tooltip("These entries are considered only if no entries from 'includedIfConditionsMet' have been includedd")] public PoolEntry[] includedIfNoConditionsMet = Array.Empty(); internal Category Upgrade() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown Category val = new Category { name = name, categoryWeight = categoryWeight }; List list = new List(); List list2 = new List(); PoolEntry[] array = alwaysIncluded; for (int i = 0; i < array.Length; i++) { PoolEntry val2 = array[i].Upgrade(); if (val2 != null && Object.op_Implicit((Object)(object)val2.dccs)) { list.Add(val2); } } val.alwaysIncluded = list.ToArray(); ConditionalPoolEntry[] array2 = includedIfConditionsMet; for (int i = 0; i < array2.Length; i++) { PoolEntry val3 = array2[i].Upgrade(); if (val3 != null) { ConditionalPoolEntry val4 = (ConditionalPoolEntry)(object)((val3 is ConditionalPoolEntry) ? val3 : null); if (val4 != null && Object.op_Implicit((Object)(object)((PoolEntry)val4).dccs)) { list2.Add(val4); } } } val.includedIfConditionsMet = list2.ToArray(); list.Clear(); array = includedIfNoConditionsMet; for (int i = 0; i < array.Length; i++) { PoolEntry val5 = array[i].Upgrade(); if (val5 != null && Object.op_Implicit((Object)(object)val5.dccs)) { list.Add(val5); } } val.includedIfNoConditionsMet = list.ToArray(); return val; } } private static HashSet instances = new HashSet(); [Tooltip("The DccsPool that will be overwritten with the values stored in this AddressableDCCSPool")] public DccsPool targetPool; [Tooltip("The categories for this pool")] public Category[] poolCategories = Array.Empty(); [SystemInitializer(new Type[] { })] private static void SystemInitializer() { AddressReferencedAsset.OnAddressReferencedAssetsLoaded += delegate { foreach (AddressableDCCSPool instance in instances) { try { instance.Upgrade(); } catch (Exception arg) { DirectorPlugin.Logger.LogError((object)$"{instance} failed to upgrade.\n{arg}"); } } }; } private void Upgrade() { List list = new List(); for (int i = 0; i < poolCategories.Length; i++) { Category val = poolCategories[i]?.Upgrade(); if (val == null) { DirectorPlugin.Logger.LogWarning((object)$"{this}'s {i}th index of categories failed to upgrade."); } else { list.Add(val); } } targetPool.poolCategories = list.ToArray(); poolCategories = null; } private void Awake() { instances.Add(this); } private void OnDestroy() { instances.Remove(this); } } [Serializable] public class AddressableDirectorCard { [Tooltip("The spawn card for this DirectorCard")] public AddressReferencedSpawnCard spawnCard; [Tooltip("The weight of this director card relative to other cards")] public int selectionWeight; [Tooltip("The distance used for spawning this card, used for monsters")] public MonsterSpawnDistance spawnDistance; public bool preventOverhead; [Tooltip("The minimum amount of stages that need to be completed before this Card can be spawned")] public int minimumStageCompletions; [Tooltip("This unlockableDef must be unlocked for this Card to spawn")] public AddressReferencedUnlockableDef requiredUnlockableDef; [Tooltip("This unlockableDef cannot be unlocked for this Card to spawn")] public AddressReferencedUnlockableDef forbiddenUnlockableDef; internal DirectorCard Upgrade() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_0029: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown return new DirectorCard { spawnCard = AddressReferencedSpawnCard.op_Implicit(spawnCard), selectionWeight = selectionWeight, spawnDistance = spawnDistance, preventOverhead = preventOverhead, minimumStageCompletions = minimumStageCompletions, requiredUnlockableDef = AddressReferencedUnlockableDef.op_Implicit(requiredUnlockableDef), forbiddenUnlockableDef = AddressReferencedUnlockableDef.op_Implicit(forbiddenUnlockableDef) }; } } [CreateAssetMenu(fileName = "New AddressableDirectorCardCategorySelection", menuName = "R2API/DirectorAPI/AddressableDirectorCardCategorySelection")] public class AddressableDirectorCardCategorySelection : ScriptableObject { [Serializable] public struct Category { [Tooltip("The name of this category")] public string name; [Tooltip("The DirectorCards for this category")] public AddressableDirectorCard[] cards; [Tooltip("The weight of this category relative to the other categories")] public float selectionWeight; internal Category? Upgrade() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) Category value = new Category { name = name, selectionWeight = selectionWeight }; List list = new List(); if (cards == null || cards.Length == 0) { DirectorPlugin.Logger.LogWarning((object)("Director card category " + name + " cannot upgrade as there are no AddressableDirectorCards. See below for more information.")); return null; } for (int i = 0; i < cards.Length; i++) { DirectorCard val = cards[i]?.Upgrade(); if (val != null) { if (!Object.op_Implicit((Object)(object)val.spawnCard)) { DirectorPlugin.Logger.LogWarning((object)$"AddressableDCCS.Category with name {name} has an invalid spawn card at index {i}"); } else { list.Add(val); } } } value.cards = list.ToArray(); return value; } } private static HashSet instances = new HashSet(); [Tooltip("The DirectorCardCategorySelection that will be overridedn with the values stored in this AddressableDirectorCardCategorySelection")] public DirectorCardCategorySelection targetCardCategorySelection; [Tooltip("The categories for this AddressableDirectorCardCategorySelection")] public Category[] categories = Array.Empty(); private void Upgrade() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) ManualLogSource logger = DirectorPlugin.Logger; List list = new List(); for (int i = 0; i < categories.Length; i++) { Category category = categories[i]; Category? val = category.Upgrade(); if (!val.HasValue) { logger.LogWarning((object)$"{this}'s {i}th category failed to upgrade."); } else if (val.Value.cards.Length == 0) { logger.LogWarning((object)$"{this}'s {i}th category failed to upgrade, no cards where computed."); } else { list.Add(val.Value); } } targetCardCategorySelection.categories = list.ToArray(); categories = null; } private void Awake() { instances.Add(this); } private void OnDestroy() { instances.Remove(this); } [SystemInitializer(new Type[] { })] private static void SystemInitializer() { AddressReferencedAsset.OnAddressReferencedAssetsLoaded += delegate { foreach (AddressableDirectorCardCategorySelection instance in instances) { try { instance.Upgrade(); } catch (Exception arg) { DirectorPlugin.Logger.LogError((object)$"{instance} failed to upgrade.\n{arg}"); } } }; } } [AutoVersion] public static class DirectorAPI { public enum MonsterCategory { Invalid, Custom, BasicMonsters, Minibosses, Champions, Special } public enum InteractableCategory { Invalid, Custom, Chests, Barrels, Shrines, Drones, Misc, Rare, Duplicator, VoidStuff, StormStuff } [Flags] public enum Stage : long { Custom = 1L, TitanicPlains = 2L, DistantRoost = 4L, WetlandAspect = 8L, AbandonedAqueduct = 0x10L, RallypointDelta = 0x20L, ScorchedAcres = 0x40L, AbyssalDepths = 0x80L, SirensCall = 0x100L, GildedCoast = 0x200L, MomentFractured = 0x400L, Bazaar = 0x800L, VoidCell = 0x1000L, MomentWhole = 0x2000L, SkyMeadow = 0x4000L, ArtifactReliquary = 0x8000L, Commencement = 0x10000L, SunderedGrove = 0x20000L, AphelianSanctuary = 0x40000L, AphelianSanctuarySimulacrum = 0x80000L, AbyssalDepthsSimulacrum = 0x100000L, RallypointDeltaSimulacrum = 0x200000L, TitanicPlainsSimulacrum = 0x400000L, AbandonedAqueductSimulacrum = 0x800000L, CommencementSimulacrum = 0x1000000L, SkyMeadowSimulacrum = 0x2000000L, SiphonedForest = 0x4000000L, SulfurPools = 0x8000000L, VoidLocus = 0x10000000L, ThePlanetarium = 0x20000000L, VerdantFalls = 0x40000000L, ViscousFalls = 0x80000000L, ArtifactReliquary_AphelianSanctuary_Theme = 0x100000000L, ArtifactReliquary_AbandonedAqueduct_Theme = 0x200000000L, ArtifactReliquary_ScorchedAcres_Theme = 0x400000000L, ShatteredAbodes = 0x800000000L, DisturbedImpact = 0x1000000000L, ReformedAltar = 0x2000000000L, TreebornColony = 0x4000000000L, GoldenDieback = 0x8000000000L, HelminthHatchery = 0x10000000000L, PrimeMeridian = 0x20000000000L, ComputationalExchange = 0x40000000000L, ConduitCanyon = 0x80000000000L, IronAlluvium = 0x100000000000L, IronAuroras = 0x200000000000L, PretendersPrecipice = 0x400000000000L, RepurposedCrater = 0x800000000000L, NeuralSanctum = 0x1000000000000L, SolutionalHaunt = 0x2000000000000L } [Serializable] public struct StageSerde { public long Value; public StageSerde(long value) { Value = value; } public static implicit operator StageSerde(Stage enumValue) { return new StageSerde((long)enumValue); } public static implicit operator Stage(StageSerde stageSerde) { return (Stage)stageSerde.Value; } } public struct StageInfo { public Stage stage; public string CustomStageName; public static StageInfo ParseInternalStageName(string internalStageName) { SetHooks(); StageInfo result = default(StageInfo); result.stage = DirectorAPI.ParseInternalStageName(internalStageName); result.CustomStageName = ((result.stage == Stage.Custom) ? "" : internalStageName); return result; } public string ToInternalStageName() { SetHooks(); string text = DirectorAPI.ToInternalStageName(stage); if (!(text == "")) { return text; } return CustomStageName; } public bool CheckStage(Stage stage, params string[] customStageNames) { SetHooks(); if (!stage.HasFlag(this.stage)) { return false; } if (this.stage == Stage.Custom && customStageNames.Length != 0) { return customStageNames.Contains(CustomStageName); } return true; } } public class StageSettings { public int SceneDirectorMonsterCredits; public int SceneDirectorInteractableCredits; public Dictionary? BonusCreditObjects; public Dictionary> MonsterCategoryWeightsPerDccs; public Dictionary> InteractableCategoryWeightsPerDccs; } public class DirectorCardHolder { public DirectorCard? Card; public MonsterCategory MonsterCategory; public string CustomMonsterCategory; public float MonsterCategorySelectionWeight = 1f; public InteractableCategory InteractableCategory; public string CustomInteractableCategory; public float InteractableCategorySelectionWeight = 1f; public bool IsMonster => MonsterCategory != MonsterCategory.Invalid; public bool IsInteractable => InteractableCategory != InteractableCategory.Invalid; public bool IsValid() { SetHooks(); if (InteractableCategory == InteractableCategory.Invalid && MonsterCategory == MonsterCategory.Invalid) { return false; } return true; } public void ThrowIfInvalid() { SetHooks(); if (!IsValid()) { throw new Exception("Both DirectorCardHolder.InteractableCategory and DirectorCardHolder.MonsterCategory are invalid"); } } public string GetCategoryName() { SetHooks(); ThrowIfInvalid(); if (InteractableCategory == InteractableCategory.Invalid) { if (MonsterCategory == MonsterCategory.Custom) { return CustomMonsterCategory; } return Helpers.GetVanillaMonsterCategoryName(MonsterCategory); } if (InteractableCategory == InteractableCategory.Custom) { return CustomInteractableCategory; } return Helpers.GetVanillaInteractableCategoryName(InteractableCategory); } } public class MonsterFamilyHolder { public Dictionary> MonsterCategoryToMonsterCards; public Dictionary MonsterCategoryToSelectionWeights; public int MinStageCompletion; public int MaxStageCompletion; public float FamilySelectionWeight; public string? SelectionChatString; } public static class Helpers { public static class MonsterNames { public static readonly string Beetle = "cscbeetle"; public static readonly string BeetleGuard = "cscbeetleguard"; public static readonly string BeetleQueen = "cscbeetlequeen"; public static readonly string BrassContraption = "cscbell"; public static readonly string BighornBison = "cscbison"; public static readonly string Mithrix = "cscbrother"; public static readonly string MithrixHurt = "cscbrotherhurt"; public static readonly string ClayDunestrider = "cscclayboss"; public static readonly string ClayTemplar = "cscclaybruiser"; public static readonly string StrikeDrone = "cscbackupdrone"; public static readonly string GunnerDrone = "cscdrone1"; public static readonly string HealingDrone = "cscdrone2"; public static readonly string TC280Prototype = "cscmegadrone"; public static readonly string OverloadingWorm = "cscelectricworm"; public static readonly string StoneGolem = "cscgolem"; public static readonly string Grandparent = "cscgrandparent"; public static readonly string Grovetender = "cscgravekeeper"; public static readonly string GreaterWisp = "cscgreaterwisp"; public static readonly string HermitCrab = "cschermitcrab"; public static readonly string Imp = "cscimp"; public static readonly string ImpOverlord = "cscimpboss"; public static readonly string Jellyfish = "cscjellyfish"; public static readonly string Lemurian = "csclemurian"; public static readonly string ElderLemurian = "csclemurianbruiser"; public static readonly string LunarChimeraExploder = "csclunarexploder"; public static readonly string LunarChimeraGolem = "csclunargolem"; public static readonly string LunarChimeraWisp = "csclunarwisp"; public static readonly string MagmaWorm = "cscmagmaworm"; public static readonly string MiniMushrum = "cscminimushroom"; public static readonly string VoidReaver = "cscnullifier"; public static readonly string VoidReaverAlly = "cscnullifierally"; public static readonly string Parent = "cscparent"; public static readonly string SolusControlUnit = "cscroboballboss"; public static readonly string SolusProbe = "cscroboballmini"; public static readonly string AlloyWorshipUnit = "cscsuperroboballboss"; public static readonly string Scavenger = "cscscav"; public static readonly string ScavengerBoss = "cscscavboss"; public static readonly string TwiptwiptheDevotee = "cscscavlunar"; public static readonly string StoneTitan = "csctitanblackbeach"; public static readonly string StoneTitanAbyssalDepths = "csctitandampcave"; public static readonly string StoneTitanGolemPlains = "csctitangolemplains"; public static readonly string StoneTitanAbandonedAqueduct = "csctitangoolake"; public static readonly string Aurelionite = "csctitangold"; public static readonly string WanderingVagrant = "cscvagrant"; public static readonly string AlloyVulture = "cscvulture"; public static readonly string LesserWisp = "csclesserwisp"; public static readonly string BeetleGuardAlly = "cscbeetleguardally"; public static readonly string DelightedProbe = "cscroboballgreenbuddy"; public static readonly string QuietProbe = "cscroboballredbuddy"; public static readonly string SquidTurret = "cscsquidturret"; public static readonly string AurelioniteAlly = "csctitangoldally"; public static readonly string Larva = "cscacidlarva"; public static readonly string Assassin = "cscassassin2"; public static readonly string ClayApothecary = "cscclaygrenadier"; public static readonly string ColDroneman = "cscdronecommander"; public static readonly string BlindPest = "cscflyingvermin"; public static readonly string BlindPestSnowy = "cscflyingverminsnowy"; public static readonly string Geep = "cscgeepbody"; public static readonly string Gip = "cscgipbody"; public static readonly string Gup = "cscgupbody"; public static readonly string MAJORCONSTRUCT_BODY_NAME = "cscmajorconstruct"; public static readonly string XiConstruct = "cscmegaconstruct"; public static readonly string AlphaConstruct = "cscminorconstruct"; public static readonly string AlphaConstructAttachable = "cscminorconstructattachable"; public static readonly string AlphaConstructOnKill = "cscminorconstructonkill"; public static readonly string BlindVermin = "cscvermin"; public static readonly string BlindVerminSnowy = "cscverminsnowy"; public static readonly string VoidBarnacle = "cscvoidbarnacle"; public static readonly string VoidBarnacleAlly = "cscvoidbarnacleally"; public static readonly string VoidBarnacleNoCast = "cscvoidbarnaclenocast"; public static readonly string VoidJailer = "cscvoidjailer"; public static readonly string VoidJailerAlly = "cscvoidjailerally"; public static readonly string VoidDevastator = "cscvoidmegacrab"; public static readonly string Voidling = "cscvoidraidcrab"; public static readonly string VoidlingJoint = "cscvoidraidcrabjoint"; public static readonly string VoidlingBase = "cscminivoidraidcrabbase"; public static readonly string VoidlingPhase1 = "cscminivoidraidcrabphase1"; public static readonly string VoidlingPhase2 = "cscminivoidraidcrabphase2"; public static readonly string VoidlingPhase3 = "cscminivoidraidcrabphase3"; public static readonly string VoidInfestor = "cscvoidinfestor"; public static readonly string MithrixInfiniteTower = "cscbrotherit"; public static readonly string ArchWisp = "cscarchwisp"; public static readonly string BeetleCrystal = "cscbeetlecrystal"; public static readonly string BeetleGuardCrystal = "cscbeetleguardcrystal"; public static readonly string MithrixGlass = "cscbrotherglass"; public static readonly string AncestralPod = "cscparentpod"; public static readonly string Child = "cscchild"; public static readonly string LunarRain = "csccorruptionspike"; public static readonly string FalseSonBossPhase1 = "cscfalsesonboss"; public static readonly string FalseSonBossPhase2 = "cscfalsesonbosslunarshard"; public static readonly string FalseSonBossPhase3 = "cscfalsesonbossbrokenlunarshard"; public static readonly string Halcyonite = "cschalcyonite"; public static readonly string Scorchling = "cscscorchling"; public static readonly string SolusInvalidator = "cscdefectiveunit"; public static readonly string LtDroneboy = "cscdronebomber"; public static readonly string CROSSHAIRS = "cscgunnerdrone"; public static readonly string CHIRP = "cscdthaulerdrone"; public static readonly string DOC = "cschealingdrone"; public static readonly string SolusExtractor = "cscextractorunit"; public static readonly string BestBuddy = "cscfriendunit"; public static readonly string BestBuddyQuestUnlock = "cscfriendunitquestunlock"; public static readonly string SolusTransporter = "cscironhauler"; public static readonly string SolusDistributor = "cscminepod"; public static readonly string SeveredScorcher = "cscsolusamalgamatorflamethrowercannon"; public static readonly string SeveredBreaker = "cscsolusamalgamatormissilepod"; public static readonly string SeveredProbe = "cscsolusamalgamatorthruster"; public static readonly string SolusAmalgamator = "cscsolusamalgamator"; public static readonly string SolusHeart = "cscsolusheart"; public static readonly string SolusMine = "cscsolusmine"; public static readonly string SolusWing = "cscsoluswing"; public static readonly string VultureHuntressInvader = "cscvulturehuntressinvader"; public static readonly string VultureMulTInvader = "cscvulturemultinvader"; public static readonly string SolusScorcher = "csctanker"; public static readonly string AlloyHunter = "cscvulturehunter"; public static readonly string SolusProspector = "cscworkerunit"; } public static class MonsterPoolCategories { public static readonly string Standard = "Standard"; public static readonly float StandardWeight = 0.98f; public static readonly string Family = "Family"; public static readonly float FamilyWeight = 0.02f; public static readonly string VoidInvasion = "VoidInvasion"; public static readonly float VoidInvasionWeight = 0.02f; } public static class InteractablePoolCategories { public static readonly string Standard = "Standard"; public static readonly float StandardWeight = 1f; } public static class InteractableNames { public static readonly string BrokenGunnerDrone = "iscbrokendrone1"; public static readonly string BrokenHealingDrone = "iscbrokendrone2"; public static readonly string BrokenEmergencyDrone = "iscbrokenemergencydrone"; public static readonly string BrokenEquipmentDrone = "iscbrokenequipmentdrone"; public static readonly string BrokenIncineratorDrone = "iscbrokenflamedrone"; public static readonly string BrokenTC280 = "iscbrokenmegadrone"; public static readonly string BrokenMissileDrone = "iscbrokenmissiledrone"; public static readonly string BrokenGunnerTurret = "iscbrokenturret1"; public static readonly string ScavengersSack = "iscscavbackpack"; public static readonly string ScavengersLunarSack = "iscscavlunarbackpack"; public static readonly string Barrel = "iscbarrel1"; public static readonly string AdaptiveChest = "isccasinochest"; public static readonly string ChestDamage = "isccategorychestdamage"; public static readonly string ChestHealing = "isccategorychesthealing"; public static readonly string ChestUtility = "isccategorychestutility"; public static readonly string Chest = "iscchest1"; public static readonly string CloakedChest = "iscchest1stealthed"; public static readonly string LargeChest = "iscchest2"; public static readonly string Printer3D = "iscduplicator"; public static readonly string Printer3DLarge = "iscduplicatorlarge"; public static readonly string PrinterMiliTech = "iscduplicatormilitary"; public static readonly string PrinterOvergrown3D = "iscduplicatorwild"; public static readonly string EquipmentBarrel = "iscequipmentbarrel"; public static readonly string LegendaryChest = "iscgoldchest"; public static readonly string LunarPod = "isclunarchest"; public static readonly string GoldPortal = "iscgoldshoresportal"; public static readonly string CelestialPortal = "iscmsportal"; public static readonly string BluePortal = "iscshopportal"; public static readonly string RadioScanner = "iscradartower"; public static readonly string Scrapper = "iscscrapper"; public static readonly string ShrineOfBlood = "iscshrineblood"; public static readonly string ShrineOfBloodSandy = "iscshrinebloodsandy"; public static readonly string ShrineOfBloodSnowy = "iscshrinebloodsnowy"; public static readonly string ShrineOftheMountain = "iscshrineboss"; public static readonly string ShrineOftheMountainSandy = "iscshrinebosssandy"; public static readonly string ShrineOftheMountainSnowy = "iscshrinebosssnowy"; public static readonly string ShrineOfChance = "iscshrinechance"; public static readonly string ShrineOfChanceSandy = "iscshrinechancesandy"; public static readonly string ShrineOfChanceSnowy = "iscshrinechancesnowy"; public static readonly string CleansingPool = "iscshrinecleanse"; public static readonly string CleansingPoolSandy = "iscshrinecleansesandy"; public static readonly string CleansingPoolSnowy = "iscshrinecleansesnowy"; public static readonly string ShrineOfCombat = "iscshrinecombat"; public static readonly string ShrineOfCombatSandy = "iscshrinecombatsandy"; public static readonly string ShrineOfCombatSnowy = "iscshrinecombatsnowy"; public static readonly string AltarOfGold = "iscshrinegoldshoresaccess"; public static readonly string ShrineOftheWoods = "iscshrinehealing"; public static readonly string ShrineOfOrder = "iscshrinerestack"; public static readonly string ShrineOfOrderSandy = "iscshrinerestacksandy"; public static readonly string ShrineOfOrderSnowy = "iscshrinerestacksnowy"; public static readonly string PrimordialTeleporter = "isclunarteleporter"; public static readonly string Teleporter = "iscteleporter"; public static readonly string TripleShop = "isctripleshop"; public static readonly string TripleShopEquipment = "isctripleshopequipment"; public static readonly string TripleShopLarge = "isctripleshoplarge"; public static readonly string HalcyonBeacon = "iscgoldshoresbeacon"; public static readonly string VoidRaidSafeWard = "iscvoidraidsafeward"; public static readonly string InfinitePortal = "iscinfinitetowerportal"; public static readonly string AssessmentFocus = "iscinfinitetowersafeward"; public static readonly string AssessmentFocusAwaitingInteraction = "iscinfinitetowersafewardawaitinginteraction"; public static readonly string LargeChestDamage = "isccategorychest2damage"; public static readonly string LargeChestHealing = "isccategorychest2healing"; public static readonly string LargeChestUtility = "isccategorychest2utility"; public static readonly string DeepVoidPortal = "iscdeepvoidportal"; public static readonly string DeepVoidSignal = "iscdeepvoidportalbattery"; public static readonly string VoidPortal = "iscvoidportal"; public static readonly string VoidSeed = "iscvoidcamp"; public static readonly string VoidCradle = "iscvoidchest"; public static readonly string Stalk = "iscvoidcoinbarrel"; public static readonly string VoidOutroPortal = "iscvoidoutroportal"; public static readonly string NewtAltar = "iscvoidsuppressor"; public static readonly string VoidPotential = "iscvoidtriple"; public static readonly string FreeChestMultiShop = "iscfreechest"; public static readonly string EncrustedLockbox = "isclockboxvoid"; public static readonly string GauntletEntranceOrb = "iscgauntletentrance"; public static readonly string SquidTurretMaster = "iscsquidturret"; public static readonly string RustyLockbox = "isclockbox"; public static readonly string AurelioniteGeode = "iscgeode"; public static readonly string DestinationPortal = "iscdestinationportal"; public static readonly string GreenPortal = "isccolossusportal"; public static readonly string HalcyonShrine = "iscshrinehalcyonite"; public static readonly string HalcyonShrineTier1 = "iscshrinehalcyonitetier1"; public static readonly string ShrineOfShaping = "iscshrinecolossusaccess"; public static readonly string DroneUpgradeStation = "iscdroneassemblystation"; public static readonly string DroneCombinerStation = "iscdronecombinerstation"; public static readonly string BrokenBombardmentDrone = "iscbrokenbombardmentdrone"; public static readonly string BrokenCleanupDrone = "iscbrokencleanupdrone"; public static readonly string BrokenFreezeDrone = "iscbrokencopycatdrone"; public static readonly string BrokenTransportDrone = "iscbrokenhaulerdrone"; public static readonly string BrokenJailerDrone = "iscbrokenjailerdrone"; public static readonly string BrokenJunkDrone = "iscbrokenjunkdrone"; public static readonly string BrokenBarrierDrone = "iscbrokenrechargedrone"; public static readonly string DroneScrapper = "iscdronescrapper"; public static readonly string MainlinePortal = "isceyeportal"; public static readonly string DefunctUnit = "iscfriendunitunlock"; public static readonly string VirtualPortal = "iscsolusshopportal"; public static readonly string CollectiveShrineOfCombat = "iscshrinecombatcollective"; public static readonly string EncryptedPortal = "ischardwareprogportal"; public static readonly string EncryptedPortalHaunt = "ischardwareprogportal_haunt"; public static readonly string VirtualPortalBackout = "iscsolusportalbackout"; public static readonly string TemporaryItemDistributor = "isctemporaryitemsshop"; public static readonly string TrippleDroneShop = "isctripledroneshop"; } public static void TryApplyChangesNow() { SetHooks(); ClassicStageInfo.instance.ApplyChanges(); ClassicStageInfo.instance.RebuildCards((DirectorCardCategorySelection)null, (DirectorCardCategorySelection)null); } public static void PreventElites(string? monsterName, bool elitesAllowed) { SetHooks(); MonsterActions += delegate(DccsPool dccsPool, List mixEnemyArtifactMonsters, StageInfo currentStage) { if (Object.op_Implicit((Object)(object)dccsPool)) { ForEachPoolEntryInDccsPool(dccsPool, delegate(PoolEntry poolEntry) { PreventElitesForPoolEntry(monsterName, elitesAllowed, poolEntry); }); } foreach (DirectorCardHolder mixEnemyArtifactMonster in mixEnemyArtifactMonsters) { PreventElite(monsterName, elitesAllowed, mixEnemyArtifactMonster.Card); } }; static void PreventElite(string? b, bool noElites, DirectorCard card) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (card != null && !((Object)(object)card.spawnCard == (Object)null) && string.Equals(((Object)card.spawnCard).name, b, StringComparison.InvariantCultureIgnoreCase)) { ((CharacterSpawnCard)card.spawnCard).noElites = noElites; } } static void PreventElitesForPoolEntry(string? monsterName2, bool elitesAllowed2, PoolEntry poolEntry) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) Category[] categories = poolEntry.dccs.categories; for (int i = 0; i < categories.Length; i++) { DirectorCard[] cards = categories[i].cards; foreach (DirectorCard card in cards) { PreventElite(monsterName2, elitesAllowed2, card); } } } } [Obsolete("Use the overload with the DirectorCardHolder instead")] public static void AddNewMonster(DirectorCard? monsterCard, MonsterCategory monsterCategory) { SetHooks(); AddNewMonster(new DirectorCardHolder { Card = monsterCard, MonsterCategory = monsterCategory }, addToFamilies: false); } public static void AddNewMonster(DirectorCardHolder? monsterCard, bool addToFamilies) { SetHooks(); AddNewMonster(monsterCard, addToFamilies, null); } public static void AddNewMonster(DirectorCardHolder? monsterCard, bool addToFamilies, Predicate predicate) { SetHooks(); MonsterActions += delegate(DccsPool dccsPool, List mixEnemyArtifactMonsters, StageInfo currentStage) { AddNewMonster(dccsPool, mixEnemyArtifactMonsters, monsterCard, addToFamilies, predicate); }; } public static void AddNewMonster(DccsPool dccsPool, List mixEnemyArtifactMonsters, DirectorCardHolder monsterCardHolder, bool addToFamilies) { SetHooks(); AddNewMonster(dccsPool, mixEnemyArtifactMonsters, monsterCardHolder, addToFamilies, null); } public static void AddNewMonster(DccsPool dccsPool, List mixEnemyArtifactMonsters, DirectorCardHolder monsterCardHolder, bool addToFamilies, Predicate predicate) { SetHooks(); if (Object.op_Implicit((Object)(object)dccsPool)) { ForEachPoolCategoryInDccsPool(dccsPool, delegate(Category poolCategory) { bool num = IsNotAFamilyCategory(poolCategory, dccsPool.poolCategories.Length); bool flag = !num; bool flag2 = addToFamilies && flag; if (num || flag2) { ForEachElementInPoolEntryArray(SelectPoolEntryArrayGearboxStyle(poolCategory), delegate(PoolEntry poolEntry) { AddMonsterToPoolEntry(monsterCardHolder, poolEntry, predicate); }); } }); } mixEnemyArtifactMonsters?.Add(monsterCardHolder); } private static bool IsNotAFamilyCategory(Category poolCategory, int poolCategoryCount) { if (poolCategoryCount > 1 && !string.IsNullOrWhiteSpace(poolCategory.name)) { return poolCategory.name == MonsterPoolCategories.Standard; } return true; } private static PoolEntry[] SelectPoolEntryArrayGearboxStyle(Category poolCategory) { if (poolCategory.alwaysIncluded.Length != 0) { return poolCategory.alwaysIncluded; } if (poolCategory.includedIfNoConditionsMet.Length != 0) { return poolCategory.includedIfNoConditionsMet; } return (PoolEntry[])(object)poolCategory.includedIfConditionsMet; } private static void AddMonsterToPoolEntry(DirectorCardHolder monsterCardHolder, PoolEntry poolEntry, Predicate predicate) { if ((predicate != null && predicate(poolEntry.dccs)) || predicate == null) { poolEntry.dccs.AddCard(monsterCardHolder); } } [Obsolete("Use the overload with the DirectorCardHolder instead")] public static void AddNewMonsterToStage(DirectorCard? monsterCard, MonsterCategory monsterCategory, Stage stage, string? customStageName = "") { SetHooks(); AddNewMonsterToStage(new DirectorCardHolder { Card = monsterCard, MonsterCategory = monsterCategory }, addToFamilies: false, stage, customStageName); } public static void AddNewMonsterToStage(DirectorCardHolder monsterCard, bool addToFamilies, Stage stage, string? customStageName = "") { SetHooks(); AddNewMonsterToStage(monsterCard, addToFamilies, null, stage, customStageName); } public static void AddNewMonsterToStage(DirectorCardHolder monsterCard, bool addToFamilies, Predicate predicate, Stage stage, string? customStageName = "") { SetHooks(); MonsterActions += delegate(DccsPool dccsPool, List mixEnemyArtifactMonsters, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { AddNewMonster(dccsPool, mixEnemyArtifactMonsters, monsterCard, addToFamilies, predicate); } }; } public static void AddNewMonsterToStagesWhere(DirectorCardHolder monsterCard, bool addToFamilies, Predicate matchStage) { SetHooks(); AddNewMonsterToStagesWhere(monsterCard, addToFamilies, matchStage, null); } public static void AddNewMonsterToStagesWhere(DirectorCardHolder monsterCard, bool addToFamilies, Predicate matchStage, Predicate predicate) { SetHooks(); MonsterActions += delegate(DccsPool dccsPool, List mixEnemyArtifactMonsters, StageInfo currentStage) { if (matchStage(currentStage)) { AddNewMonster(dccsPool, mixEnemyArtifactMonsters, monsterCard, addToFamilies, predicate); } }; } [Obsolete("Use the overload with the DirectorCardHolder instead")] public static void AddNewInteractable(DirectorCard? interactableCard, InteractableCategory interactableCategory) { SetHooks(); AddNewInteractable(new DirectorCardHolder { Card = interactableCard, InteractableCategory = interactableCategory }); } public static void AddNewInteractable(DirectorCardHolder? interactableCardHolder) { SetHooks(); AddNewInteractable(interactableCardHolder, null); } public static void AddNewInteractable(DirectorCardHolder? interactableCardHolder, Predicate predicate) { SetHooks(); InteractableActions += delegate(DccsPool interactablesDccsPool, StageInfo currentStage) { AddNewInteractableToStage(interactablesDccsPool, interactableCardHolder, predicate); }; } [Obsolete("Use the overload with the DirectorCardHolder instead")] public static void AddNewInteractableToStage(DirectorCard? interactableCard, InteractableCategory interactableCategory, Stage stage, string? customStageName = "") { SetHooks(); AddNewInteractableToStage(new DirectorCardHolder { Card = interactableCard, InteractableCategory = interactableCategory }, stage, customStageName); } public static void AddNewInteractableToStage(DirectorCardHolder interactableCardHolder, Stage stage, string customStageName = "") { SetHooks(); AddNewInteractableToStage(interactableCardHolder, null, stage, customStageName); } public static void AddNewInteractableToStage(DirectorCardHolder interactableCardHolder, Predicate predicate, Stage stage, string customStageName = "") { SetHooks(); InteractableActions += delegate(DccsPool interactablesDccsPool, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { AddNewInteractableToStage(interactablesDccsPool, interactableCardHolder, predicate); } }; } private static void AddNewInteractableToStage(DccsPool interactablesDccsPool, DirectorCardHolder interactableCardHolder, Predicate predicate) { if (!Object.op_Implicit((Object)(object)interactablesDccsPool)) { return; } ForEachPoolCategoryInDccsPool(interactablesDccsPool, delegate(Category poolCategory) { ForEachElementInPoolEntryArray(SelectPoolEntryArrayGearboxStyle(poolCategory), delegate(PoolEntry poolEntry) { AddInteractableToPoolEntry(interactableCardHolder, poolEntry, predicate); }); }); } private static void AddInteractableToPoolEntry(DirectorCardHolder interactableCardHolder, PoolEntry poolEntry, Predicate predicate) { if ((predicate != null && predicate(poolEntry.dccs)) || predicate == null) { poolEntry.dccs.AddCard(interactableCardHolder); } } public static void RemoveExistingMonster(string? monsterName) { SetHooks(); RemoveExistingMonster(monsterName, removeFromFamilies: true, null); } public static void RemoveExistingMonster(string? monsterName, bool removeFromFamilies, Predicate predicate) { SetHooks(); StringUtils.ThrowIfStringIsNullOrWhiteSpace(monsterName, "monsterName"); string monsterNameLowered = monsterName.ToLowerInvariant(); MonsterActions += delegate(DccsPool dccsPool, List mixEnemyArtifactMonsters, StageInfo currentStage) { RemoveExistingMonster(dccsPool, mixEnemyArtifactMonsters, monsterNameLowered, removeFromFamilies, predicate); }; } private static void RemoveExistingMonster(DccsPool dccsPool, List mixEnemyArtifactMonsters, string monsterNameLowered, bool removeFromFamilies, Predicate predicate) { if (Object.op_Implicit((Object)(object)dccsPool)) { ForEachPoolCategoryInDccsPool(dccsPool, delegate(Category poolCategory) { bool num = IsNotAFamilyCategory(poolCategory, dccsPool.poolCategories.Length); bool flag = !num; bool flag2 = removeFromFamilies && flag; if (num || flag2) { ForEachPoolEntryInDccsPoolCategory(poolCategory, delegate(PoolEntry poolEntry) { RemoveMonsterFromPoolEntry(monsterNameLowered, poolEntry, predicate); }); } }); } mixEnemyArtifactMonsters.RemoveAll((DirectorCardHolder card) => card != null && card.Card != null && Object.op_Implicit((Object)(object)card.Card.spawnCard) && ((Object)card.Card.spawnCard).name.ToLowerInvariant() == monsterNameLowered); } private static void RemoveMonsterFromPoolEntry(string monsterNameLowered, PoolEntry poolEntry, Predicate predicate) { if ((predicate == null || !predicate(poolEntry.dccs)) && predicate != null) { return; } for (int i = 0; i < poolEntry.dccs.categories.Length; i++) { List list = poolEntry.dccs.categories[i].cards.ToList(); list.RemoveAll((DirectorCard card) => card != null && Object.op_Implicit((Object)(object)card.spawnCard) && ((Object)card.spawnCard).name?.ToLowerInvariant() == monsterNameLowered); poolEntry.dccs.categories[i].cards = list.ToArray(); } } public static void RemoveExistingMonsterFromStage(string? monsterName, Stage stage, string? customStageName = "") { SetHooks(); RemoveExistingMonsterFromStage(monsterName, removeFromFamilies: false, null, stage, customStageName); } public static void RemoveExistingMonsterFromStage(string? monsterName, bool removeFromFamilies, Predicate predicate, Stage stage, string? customStageName = "") { SetHooks(); StringUtils.ThrowIfStringIsNullOrWhiteSpace(monsterName, "monsterName"); string monsterNameLowered = monsterName.ToLowerInvariant(); MonsterActions += delegate(DccsPool dccsPool, List mixEnemyArtifactMonsters, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { RemoveExistingMonster(dccsPool, mixEnemyArtifactMonsters, monsterNameLowered, removeFromFamilies, predicate); } }; } public static void RemoveExistingInteractable(string? interactableName) { SetHooks(); RemoveExistingInteractable(interactableName, null); } public static void RemoveExistingInteractable(string? interactableName, Predicate predicate) { SetHooks(); StringUtils.ThrowIfStringIsNullOrWhiteSpace(interactableName, "interactableName"); string interactableNameLowered = interactableName.ToLowerInvariant(); InteractableActions += delegate(DccsPool interactablesDccsPool, StageInfo currentStage) { RemoveExistingInteractable(interactablesDccsPool, interactableNameLowered, predicate); }; } public static void RemoveExistingInteractableFromStage(string? interactableName, Stage stage, string? customStageName = "") { SetHooks(); RemoveExistingInteractableFromStage(interactableName, null, stage, customStageName); } public static void RemoveExistingInteractableFromStage(string? interactableName, Predicate predicate, Stage stage, string? customStageName = "") { SetHooks(); StringUtils.ThrowIfStringIsNullOrWhiteSpace(interactableName, "interactableName"); string interactableNameLowered = interactableName.ToLowerInvariant(); InteractableActions += delegate(DccsPool interactablesDccsPool, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { RemoveExistingInteractable(interactablesDccsPool, interactableNameLowered, predicate); } }; } private static void RemoveExistingInteractable(DccsPool interactablesDccsPool, string interactableNameLowered, Predicate predicate) { if (Object.op_Implicit((Object)(object)interactablesDccsPool)) { ForEachPoolEntryInDccsPool(interactablesDccsPool, delegate(PoolEntry poolEntry) { RemoveInteractableFromPoolEntry(interactableNameLowered, poolEntry, predicate); }); } } private static void RemoveInteractableFromPoolEntry(string interactableNameLowered, PoolEntry poolEntry, Predicate predicate) { if ((predicate == null || !predicate(poolEntry.dccs)) && predicate != null) { return; } for (int i = 0; i < poolEntry.dccs.categories.Length; i++) { List list = poolEntry.dccs.categories[i].cards.ToList(); list.RemoveAll((DirectorCard card) => card != null && Object.op_Implicit((Object)(object)card.spawnCard) && ((Object)card.spawnCard).name?.ToLowerInvariant() == interactableNameLowered); poolEntry.dccs.categories[i].cards = list.ToArray(); } } public static void AddSceneMonsterCredits(int increase, Stage stage, string? customStageName = "") { SetHooks(); StageSettingsActions += delegate(StageSettings settings, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { settings.SceneDirectorMonsterCredits += increase; } }; } public static void AddSceneInteractableCredits(int increase, Stage stage, string? customStageName = "") { SetHooks(); StageSettingsActions += delegate(StageSettings settings, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { settings.SceneDirectorInteractableCredits += increase; } }; } public static void MultiplySceneMonsterCredits(int multiplier, Stage stage, string? customStageName = "") { SetHooks(); StageSettingsActions += delegate(StageSettings settings, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { settings.SceneDirectorMonsterCredits *= multiplier; } }; } public static void MultiplySceneInteractableCredits(int multiplier, Stage stage, string? customStageName = "") { SetHooks(); StageSettingsActions += delegate(StageSettings settings, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { settings.SceneDirectorInteractableCredits *= multiplier; } }; } public static void ReduceSceneMonsterCredits(int divisor, Stage stage, string? customStageName = "") { SetHooks(); StageSettingsActions += delegate(StageSettings settings, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { settings.SceneDirectorMonsterCredits /= divisor; } }; } public static void ReduceSceneInteractableCredits(int divisor, Stage stage, string? customStageName = "") { SetHooks(); StageSettingsActions += delegate(StageSettings settings, StageInfo currentStage) { if (currentStage.stage == stage && currentStage.CheckStage(stage, customStageName)) { settings.SceneDirectorInteractableCredits /= divisor; } }; } public static void ForEachPoolEntryInDccsPool(DccsPool dccsPool, Action action) { SetHooks(); ForEachPoolCategoryInDccsPool(dccsPool, delegate(Category poolCategory) { ForEachPoolEntryInDccsPoolCategory(poolCategory, action); }); } public static void ForEachPoolCategoryInDccsPool(DccsPool dccsPool, Action action) { SetHooks(); Category[] poolCategories = dccsPool.poolCategories; foreach (Category obj in poolCategories) { try { action(obj); } catch (Exception ex) { DirectorPlugin.Logger.LogError((object)ex); } } } public static void ForEachPoolEntryInDccsPoolCategory(Category dccsPoolCategory, Action action) { SetHooks(); ForEachElementInPoolEntryArray(dccsPoolCategory.alwaysIncluded, action); ForEachElementInPoolEntryArray(dccsPoolCategory.includedIfNoConditionsMet, action); PoolEntry[] includedIfConditionsMet = (PoolEntry[])(object)dccsPoolCategory.includedIfConditionsMet; ForEachElementInPoolEntryArray(includedIfConditionsMet, action); } private static void ForEachElementInPoolEntryArray(PoolEntry[] poolEntries, Action action) { foreach (PoolEntry obj in poolEntries) { try { action(obj); } catch (Exception ex) { DirectorPlugin.Logger.LogError((object)ex); } } } public static bool IsSameMonsterCategory(ref Category category, MonsterCategory monsterCategory) { SetHooks(); return GetMonsterCategory(category.name) == monsterCategory; } public static MonsterCategory GetMonsterCategory(string categoryString) { SetHooks(); if (string.IsNullOrWhiteSpace(categoryString)) { throw new ArgumentException("categoryString"); } return categoryString switch { "Champions" => MonsterCategory.Champions, "Minibosses" => MonsterCategory.Minibosses, "Basic Monsters" => MonsterCategory.BasicMonsters, "Special" => MonsterCategory.Special, _ => MonsterCategory.Custom, }; } public static string GetVanillaMonsterCategoryName(MonsterCategory monsterCategory) { SetHooks(); switch (monsterCategory) { case MonsterCategory.BasicMonsters: return "Basic Monsters"; case MonsterCategory.Champions: return "Champions"; case MonsterCategory.Minibosses: return "Minibosses"; case MonsterCategory.Special: return "Special"; default: { int num = (int)monsterCategory; throw new ArgumentException(num.ToString()); } } } public static InteractableCategory GetInteractableCategory(string categoryString) { SetHooks(); if (string.IsNullOrWhiteSpace(categoryString)) { throw new ArgumentException("categoryString"); } if (categoryString.Contains("Storm Stuff")) { return InteractableCategory.StormStuff; } return categoryString switch { "Chests" => InteractableCategory.Chests, "Barrels" => InteractableCategory.Barrels, "Shrines" => InteractableCategory.Shrines, "Drones" => InteractableCategory.Drones, "Misc" => InteractableCategory.Misc, "Rare" => InteractableCategory.Rare, "Duplicator" => InteractableCategory.Duplicator, "Void Stuff" => InteractableCategory.VoidStuff, _ => InteractableCategory.Custom, }; } public static string GetVanillaInteractableCategoryName(InteractableCategory interactableCategory) { SetHooks(); switch (interactableCategory) { case InteractableCategory.Chests: return "Chests"; case InteractableCategory.Barrels: return "Barrels"; case InteractableCategory.Shrines: return "Shrines"; case InteractableCategory.Drones: return "Drones"; case InteractableCategory.Misc: return "Misc"; case InteractableCategory.Rare: return "Rare"; case InteractableCategory.Duplicator: return "Duplicator"; case InteractableCategory.VoidStuff: return "Void Stuff"; case InteractableCategory.StormStuff: return "Storm Stuff"; default: { int num = (int)interactableCategory; throw new ArgumentException(num.ToString()); } } } public static bool IsSameInteractableCategory(ref Category category, InteractableCategory interactableCategory) { SetHooks(); return GetInteractableCategory(category.name) == interactableCategory; } } public delegate void GetCombatDirectorActivityCountDelegate(CombatDirector combatDirector, ref int activityCount); public class OriginalClassicStageInfo { public List monsterDccsPoolCategories; public DirectorCardCategorySelection monsterCategories; public List possibleMonsterFamilies; public List interactableDccsPoolCategories; public DirectorCardCategorySelection interactableCategories; } [CompilerGenerated] private static class <>O { public static hook_Start <0>__ApplyChangesOnStart; public static Manipulator <1>__SwapVanillaDccsWithOurs; public static hook_Init <2>__InitStageEnumToSceneDefs; public static hook_OnEnable <3>__AddRunCombatDirectorsFixedUpdateComponent; public static Manipulator <4>__CombatDirector_FixedUpdate; public static hook_Awake <5>__CombatDirector_Awake; public static Func <6>__HandleCombatDirectorInactivity; public static Func <7>__SwapDccs; } public const string PluginGUID = "com.bepis.r2api.director"; public const string PluginName = "R2API.Director"; private static DirectorCardCategorySelection _dccsMixEnemyArtifact; private static bool _hooksEnabled = false; internal static HashSet _currentStageCombatDirectorsHashSet = new HashSet(); internal static List _allCombatDirectors = new List(); private static readonly Dictionary _classicStageInfoNameToOriginalClassicStageInfos = new Dictionary(); public const string PluginVersion = "3.1.0"; [Obsolete("All submodules are automatically loaded and this property is now unused")] public static bool Loaded => true; public static Dictionary VanillaStageToSceneDefs { get; private set; } = new Dictionary(); public static event GetCombatDirectorActivityCountDelegate GetCombatDirectorActivityCount { add { SetHooks(); _getCombatDirectorActivityCount += value; } remove { _getCombatDirectorActivityCount -= value; } } public static event Action? StageSettingsActions; public static event Action, StageInfo>? MonsterActions; public static event Action? MixEnemiesDccsActions; public static event Action? InteractableActions; private static event GetCombatDirectorActivityCountDelegate _getCombatDirectorActivityCount; public static Stage ParseInternalStageName(string internalStageName) { return internalStageName switch { "golemplains" => Stage.TitanicPlains, "blackbeach" => Stage.DistantRoost, "foggyswamp" => Stage.WetlandAspect, "goolake" => Stage.AbandonedAqueduct, "frozenwall" => Stage.RallypointDelta, "wispgraveyard" => Stage.ScorchedAcres, "dampcavesimple" => Stage.AbyssalDepths, "shipgraveyard" => Stage.SirensCall, "goldshores" => Stage.GildedCoast, "mysteryspace" => Stage.MomentFractured, "bazaar" => Stage.Bazaar, "arena" => Stage.VoidCell, "limbo" => Stage.MomentWhole, "skymeadow" => Stage.SkyMeadow, "artifactworld" => Stage.ArtifactReliquary, "moon2" => Stage.Commencement, "rootjungle" => Stage.SunderedGrove, "ancientloft" => Stage.AphelianSanctuary, "itancientloft" => Stage.AphelianSanctuarySimulacrum, "itdampcave" => Stage.AbyssalDepthsSimulacrum, "itfrozenwall" => Stage.RallypointDeltaSimulacrum, "itgolemplains" => Stage.TitanicPlainsSimulacrum, "itgoolake" => Stage.AbandonedAqueductSimulacrum, "itmoon" => Stage.CommencementSimulacrum, "itskymeadow" => Stage.SkyMeadowSimulacrum, "snowyforest" => Stage.SiphonedForest, "sulfurpools" => Stage.SulfurPools, "voidraid" => Stage.ThePlanetarium, "voidstage" => Stage.VoidLocus, "lakes" => Stage.VerdantFalls, "lakesnight" => Stage.ViscousFalls, "artifactworld01" => Stage.ArtifactReliquary_AphelianSanctuary_Theme, "artifactworld02" => Stage.ArtifactReliquary_AbandonedAqueduct_Theme, "artifactworld03" => Stage.ArtifactReliquary_ScorchedAcres_Theme, "village" => Stage.ShatteredAbodes, "villagenight" => Stage.DisturbedImpact, "lemuriantemple" => Stage.ReformedAltar, "habitat" => Stage.TreebornColony, "habitatfall" => Stage.GoldenDieback, "helminthroost" => Stage.HelminthHatchery, "meridian" => Stage.PrimeMeridian, "computationalexchange" => Stage.ComputationalExchange, "conduitcanyon" => Stage.ConduitCanyon, "ironalluvium" => Stage.IronAlluvium, "ironalluvium2" => Stage.IronAuroras, "nest" => Stage.PretendersPrecipice, "repurposedcrater" => Stage.RepurposedCrater, "solusweb" => Stage.NeuralSanctum, "solutionalhaunt" => Stage.SolutionalHaunt, _ => Stage.Custom, }; } public static Stage GetStageEnumFromSceneDef(SceneDef sceneDef) { return ParseInternalStageName(sceneDef.baseSceneName); } public static string ToInternalStageName(Stage stage) { return stage switch { Stage.TitanicPlains => "golemplains", Stage.DistantRoost => "blackbeach", Stage.WetlandAspect => "foggyswamp", Stage.AbandonedAqueduct => "goolake", Stage.RallypointDelta => "frozenwall", Stage.ScorchedAcres => "wispgraveyard", Stage.AbyssalDepths => "dampcavesimple", Stage.SirensCall => "shipgraveyard", Stage.GildedCoast => "goldshores", Stage.MomentFractured => "mysteryspace", Stage.Bazaar => "bazaar", Stage.VoidCell => "arena", Stage.MomentWhole => "limbo", Stage.SkyMeadow => "skymeadow", Stage.ArtifactReliquary => "artifactworld", Stage.Commencement => "moon2", Stage.SunderedGrove => "rootjungle", Stage.AphelianSanctuary => "ancientloft", Stage.AphelianSanctuarySimulacrum => "itancientloft", Stage.AbyssalDepthsSimulacrum => "itdampcave", Stage.RallypointDeltaSimulacrum => "itfrozenwall", Stage.TitanicPlainsSimulacrum => "itgolemplains", Stage.AbandonedAqueductSimulacrum => "itgoolake", Stage.CommencementSimulacrum => "itmoon", Stage.SkyMeadowSimulacrum => "itskymeadow", Stage.SiphonedForest => "snowyforest", Stage.SulfurPools => "sulfurpools", Stage.VoidLocus => "voidstage", Stage.ThePlanetarium => "voidraid", Stage.VerdantFalls => "lakes", Stage.ViscousFalls => "lakesnight", Stage.ArtifactReliquary_AphelianSanctuary_Theme => "artifactworld01", Stage.ArtifactReliquary_AbandonedAqueduct_Theme => "artifactworld02", Stage.ArtifactReliquary_ScorchedAcres_Theme => "artifactworld03", Stage.ShatteredAbodes => "village", Stage.DisturbedImpact => "villagenight", Stage.ReformedAltar => "lemuriantemple", Stage.TreebornColony => "habitat", Stage.GoldenDieback => "habitatfall", Stage.HelminthHatchery => "helminthroost", Stage.PrimeMeridian => "meridian", Stage.ComputationalExchange => "computationalexchange", Stage.ConduitCanyon => "conduitcanyon", Stage.IronAlluvium => "ironalluvium", Stage.IronAuroras => "ironalluvium2", Stage.PretendersPrecipice => "nest", Stage.RepurposedCrater => "repurposedcrater", Stage.NeuralSanctum => "solusweb", Stage.SolutionalHaunt => "solutionalhaunt", _ => "", }; } public static int AddCard(this DirectorCardCategorySelection dccs, DirectorCardHolder cardHolder) { SetHooks(); string categoryName = cardHolder.GetCategoryName(); for (int i = 0; i < dccs.categories.Length; i++) { if (dccs.categories[i].name.Contains(categoryName, StringComparison.InvariantCultureIgnoreCase)) { ArrayUtils.ArrayAppend(ref dccs.categories[i].cards, ref cardHolder.Card); return dccs.categories[i].cards.Length - 1; } } float num = (cardHolder.IsMonster ? cardHolder.MonsterCategorySelectionWeight : cardHolder.InteractableCategorySelectionWeight); int num2 = dccs.AddCategory(categoryName, num); return dccs.AddCard(num2, cardHolder.Card); } public static bool IsStageCombatDirector(this CombatDirector combatDirector) { return IsStageCombatDirectorInternal(combatDirector); } internal static void SetHooks() { //IL_000d: 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_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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown if (!_hooksEnabled) { AsyncOperationHandle val = LegacyResourcesAPI.LoadAsync("DirectorCardCategorySelections/dccsMixEnemy"); val.Completed += delegate(AsyncOperationHandle x) { RoR2Content.mixEnemyMonsterCards = x.Result; }; object obj = <>O.<0>__ApplyChangesOnStart; if (obj == null) { hook_Start val2 = ApplyChangesOnStart; <>O.<0>__ApplyChangesOnStart = val2; obj = (object)val2; } ClassicStageInfo.Start += (hook_Start)obj; object obj2 = <>O.<1>__SwapVanillaDccsWithOurs; if (obj2 == null) { Manipulator val3 = SwapVanillaDccsWithOurs; <>O.<1>__SwapVanillaDccsWithOurs = val3; obj2 = (object)val3; } ClassicStageInfo.HandleMixEnemyArtifact += (Manipulator)obj2; object obj3 = <>O.<2>__InitStageEnumToSceneDefs; if (obj3 == null) { hook_Init val4 = InitStageEnumToSceneDefs; <>O.<2>__InitStageEnumToSceneDefs = val4; obj3 = (object)val4; } SceneCatalog.Init += (hook_Init)obj3; object obj4 = <>O.<3>__AddRunCombatDirectorsFixedUpdateComponent; if (obj4 == null) { hook_OnEnable val5 = AddRunCombatDirectorsFixedUpdateComponent; <>O.<3>__AddRunCombatDirectorsFixedUpdateComponent = val5; obj4 = (object)val5; } DirectorCore.OnEnable += (hook_OnEnable)obj4; object obj5 = <>O.<4>__CombatDirector_FixedUpdate; if (obj5 == null) { Manipulator val6 = CombatDirector_FixedUpdate; <>O.<4>__CombatDirector_FixedUpdate = val6; obj5 = (object)val6; } CombatDirector.FixedUpdate += (Manipulator)obj5; object obj6 = <>O.<5>__CombatDirector_Awake; if (obj6 == null) { hook_Awake val7 = CombatDirector_Awake; <>O.<5>__CombatDirector_Awake = val7; obj6 = (object)val7; } CombatDirector.Awake += (hook_Awake)obj6; _hooksEnabled = true; } } internal static void UnsetHooks() { //IL_0010: 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) //IL_001b: Expected O, but got Unknown //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: Expected O, but got Unknown //IL_0050: 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_005b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown object obj = <>O.<0>__ApplyChangesOnStart; if (obj == null) { hook_Start val = ApplyChangesOnStart; <>O.<0>__ApplyChangesOnStart = val; obj = (object)val; } ClassicStageInfo.Start -= (hook_Start)obj; object obj2 = <>O.<1>__SwapVanillaDccsWithOurs; if (obj2 == null) { Manipulator val2 = SwapVanillaDccsWithOurs; <>O.<1>__SwapVanillaDccsWithOurs = val2; obj2 = (object)val2; } ClassicStageInfo.HandleMixEnemyArtifact -= (Manipulator)obj2; object obj3 = <>O.<2>__InitStageEnumToSceneDefs; if (obj3 == null) { hook_Init val3 = InitStageEnumToSceneDefs; <>O.<2>__InitStageEnumToSceneDefs = val3; obj3 = (object)val3; } SceneCatalog.Init -= (hook_Init)obj3; object obj4 = <>O.<3>__AddRunCombatDirectorsFixedUpdateComponent; if (obj4 == null) { hook_OnEnable val4 = AddRunCombatDirectorsFixedUpdateComponent; <>O.<3>__AddRunCombatDirectorsFixedUpdateComponent = val4; obj4 = (object)val4; } DirectorCore.OnEnable -= (hook_OnEnable)obj4; object obj5 = <>O.<4>__CombatDirector_FixedUpdate; if (obj5 == null) { Manipulator val5 = CombatDirector_FixedUpdate; <>O.<4>__CombatDirector_FixedUpdate = val5; obj5 = (object)val5; } CombatDirector.FixedUpdate -= (Manipulator)obj5; object obj6 = <>O.<5>__CombatDirector_Awake; if (obj6 == null) { hook_Awake val6 = CombatDirector_Awake; <>O.<5>__CombatDirector_Awake = val6; obj6 = (object)val6; } CombatDirector.Awake -= (hook_Awake)obj6; _hooksEnabled = false; } private static void CombatDirector_Awake(orig_Awake orig, CombatDirector self) { orig.Invoke(self); _allCombatDirectors.Add(self); } private static void CombatDirector_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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel iLLabel = null; if (!val.TryGotoNext((MoveType)2, new Func[3] { (Instruction x) => ILPatternMatchingExt.MatchCall(x, (MethodBase)Reflection.GetPropertyGetter(typeof(Run), "instance")), (Instruction x) => ILPatternMatchingExt.MatchCall(x, "op_Implicit"), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref iLLabel) })) { DirectorPlugin.Logger.LogError((object)(((MemberReference)il.Method).Name + " IL Hook failed!")); return; } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)HandleCombatDirectorInactivity); val.Emit(OpCodes.Brfalse_S, (object)iLLabel); } private static bool HandleCombatDirectorInactivity(CombatDirector combatDirector) { if (!((Behaviour)combatDirector).enabled) { return true; } int activityCount = 0; DirectorAPI._getCombatDirectorActivityCount?.Invoke(combatDirector, ref activityCount); if (activityCount < 0) { return false; } return true; } internal static bool HandleCombatDirectorActivity(CombatDirector combatDirector) { if (((Behaviour)combatDirector).enabled || combatDirector.moneyWaves == null) { return false; } int activityCount = 0; DirectorAPI._getCombatDirectorActivityCount?.Invoke(combatDirector, ref activityCount); if (activityCount > 0) { return true; } return false; } private static void AddRunCombatDirectorsFixedUpdateComponent(orig_OnEnable orig, DirectorCore self) { orig.Invoke(self); UnityObjectExtensions.EnsureComponent(((Component)self).gameObject); } private static void ApplyChangesOnStart(orig_Start orig, ClassicStageInfo classicStageInfo) { classicStageInfo.PortToNewSystem(); classicStageInfo.ApplyChanges(); orig.Invoke(classicStageInfo); } private static void SwapVanillaDccsWithOurs(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext(new Func[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, "CopyFrom") })) { val.EmitDelegate>((Func)SwapDccs); } static DirectorCardCategorySelection SwapDccs(DirectorCardCategorySelection vanillaDccs) { return _dccsMixEnemyArtifact; } } private static IEnumerator InitStageEnumToSceneDefs(orig_Init orig) { yield return orig.Invoke(); foreach (IGrouping item in from sceneDef in (IEnumerable)(object)SceneCatalog.allStageSceneDefs group sceneDef by GetStageEnumFromSceneDef(sceneDef)) { VanillaStageToSceneDefs[item.Key] = item.ToArray(); } } private static void PortToNewSystem(this ClassicStageInfo classicStageInfo) { PortToNewMonsterSystem(classicStageInfo); PortToNewInteractableSystem(classicStageInfo); } internal static void ApplyChanges(this ClassicStageInfo classicStageInfo) { StageInfo stageInfo = GetStageInfo(classicStageInfo); BackupOrRestoreClassicStageInfoToOriginalState(classicStageInfo, stageInfo); ApplyMonsterChanges(classicStageInfo, stageInfo); ApplyInteractableChanges(classicStageInfo, stageInfo); ApplySettingsChanges(classicStageInfo, stageInfo); } private static StageInfo GetStageInfo(ClassicStageInfo classicStageInfo) { StageInfo result = new StageInfo { stage = Stage.Custom, CustomStageName = "" }; SceneInfo component = ((Component)classicStageInfo).GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { return result; } SceneDef sceneDef = component.sceneDef; if (!Object.op_Implicit((Object)(object)sceneDef)) { return result; } result.stage = GetStageEnumFromSceneDef(sceneDef); if (result.stage == Stage.Custom) { result.CustomStageName = sceneDef.baseSceneName; } return result; } private static void ApplySettingsChanges(ClassicStageInfo classicStageInfo, StageInfo stageInfo) { StageSettings stageSettings = GetStageSettings(classicStageInfo); if (DirectorAPI.StageSettingsActions != null) { Delegate[] invocationList = DirectorAPI.StageSettingsActions.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(stageSettings, stageInfo); } catch (Exception ex) { DirectorPlugin.Logger.LogError((object)ex); } } } SetStageSettings(classicStageInfo, stageSettings); } private static void PortToNewMonsterSystem(ClassicStageInfo classicStageInfo) { if (!Object.op_Implicit((Object)(object)classicStageInfo.monsterDccsPool) && Object.op_Implicit((Object)(object)classicStageInfo.monsterCategories)) { DirectorPlugin.Logger.LogInfo((object)"Current scene is using old monster dccs system, porting to new one"); DccsPool val = ScriptableObject.CreateInstance(); ((Object)val).name = "R2API_dp" + ((Object)classicStageInfo).name + "Monsters"; List list = new List(); PortOldStandardMonsterCategoriesToNewDccsPoolSystem(classicStageInfo.monsterCategories, list); if (classicStageInfo.possibleMonsterFamilies != null) { PortOldMonsterFamiliesToNewDccsPoolSystem(classicStageInfo.possibleMonsterFamilies, list); } val.poolCategories = list.ToArray(); classicStageInfo.monsterDccsPool = val; } } private static void PortOldStandardMonsterCategoriesToNewDccsPoolSystem(DirectorCardCategorySelection monsterCategories, List dccsPoolCategories) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0053: Expected O, but got Unknown Category val = new Category(); val.name = Helpers.MonsterPoolCategories.Standard; val.categoryWeight = Helpers.MonsterPoolCategories.StandardWeight; val.alwaysIncluded = Array.Empty(); val.includedIfConditionsMet = Array.Empty(); val.includedIfNoConditionsMet = (PoolEntry[])(object)new PoolEntry[1] { new PoolEntry { dccs = monsterCategories, weight = 1f } }; dccsPoolCategories.Add(val); } private static void PortOldMonsterFamiliesToNewDccsPoolSystem(MonsterFamily[] possibleMonsterFamilies, List dccsPoolCategories) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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_0079: Expected O, but got Unknown Category val = new Category(); val.name = Helpers.MonsterPoolCategories.Family; val.categoryWeight = ClassicStageInfo.monsterFamilyChance; val.alwaysIncluded = Array.Empty(); List list = new List(); foreach (MonsterFamily val2 in possibleMonsterFamilies) { DirectorCardCategorySelection monsterFamilyCategories = val2.monsterFamilyCategories; FamilyDirectorCardCategorySelection val3 = (FamilyDirectorCardCategorySelection)(object)((monsterFamilyCategories is FamilyDirectorCardCategorySelection) ? monsterFamilyCategories : null); if (val3 != null) { list.Add(new ConditionalPoolEntry { dccs = (DirectorCardCategorySelection)(object)val3, weight = val2.selectionWeight, requiredExpansions = Array.Empty() }); } else { DirectorPlugin.Logger.LogError((object)("classicStageInfo.possibleMonsterFamilies " + ((Object)val2.monsterFamilyCategories).name + " not setup correctly")); } } val.includedIfConditionsMet = list.ToArray(); val.includedIfNoConditionsMet = Array.Empty(); dccsPoolCategories.Add(val); } private static void PortToNewInteractableSystem(ClassicStageInfo classicStageInfo) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)classicStageInfo.interactableDccsPool) && Object.op_Implicit((Object)(object)classicStageInfo.interactableCategories)) { DirectorPlugin.Logger.LogInfo((object)"Current scene is using old interactable dccs system, porting to new one"); DccsPool val = ScriptableObject.CreateInstance(); ((Object)val).name = "R2API_dp" + ((Object)classicStageInfo).name + "Interactables"; List list = new List(); Category val2 = new Category(); val2.name = Helpers.InteractablePoolCategories.Standard; val2.categoryWeight = Helpers.InteractablePoolCategories.StandardWeight; val2.alwaysIncluded = Array.Empty(); val2.includedIfConditionsMet = Array.Empty(); val2.includedIfNoConditionsMet = (PoolEntry[])(object)new PoolEntry[1] { new PoolEntry { dccs = classicStageInfo.interactableCategories, weight = 1f } }; list.Add(val2); val.poolCategories = list.ToArray(); classicStageInfo.interactableDccsPool = val; } } private static void ApplyMonsterChanges(ClassicStageInfo classicStageInfo, StageInfo stageInfo) { InitCustomMixEnemyArtifactDccs(); List directorCardHoldersFromDCCS = GetDirectorCardHoldersFromDCCS(_dccsMixEnemyArtifact); Delegate[] invocationList; if (DirectorAPI.MonsterActions != null) { invocationList = DirectorAPI.MonsterActions.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action, StageInfo> action = (Action, StageInfo>)invocationList[i]; try { action(classicStageInfo.monsterDccsPool, directorCardHoldersFromDCCS, stageInfo); } catch (Exception ex) { DirectorPlugin.Logger.LogError((object)ex); } } } ApplyNewCardHoldersToDCCS(_dccsMixEnemyArtifact, directorCardHoldersFromDCCS); if (DirectorAPI.MixEnemiesDccsActions == null) { return; } invocationList = DirectorAPI.MixEnemiesDccsActions.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action2 = (Action)invocationList[i]; try { action2(_dccsMixEnemyArtifact); } catch (Exception ex2) { DirectorPlugin.Logger.LogError((object)ex2); } } } private static void BackupOrRestoreClassicStageInfoToOriginalState(ClassicStageInfo classicStageInfo, StageInfo stageInfo) { string key = ((stageInfo.stage == Stage.Custom) ? stageInfo.CustomStageName : stageInfo.stage.ToString()); if (!_classicStageInfoNameToOriginalClassicStageInfos.TryGetValue(key, out OriginalClassicStageInfo value)) { BackupClassicStageInfoToOriginalState(classicStageInfo, key); } else { RestoreClassicStageInfoToOriginalState(classicStageInfo, value); } } private static void BackupClassicStageInfoToOriginalState(ClassicStageInfo classicStageInfo, string key) { OriginalClassicStageInfo originalClassicStageInfo = new OriginalClassicStageInfo(); if (Object.op_Implicit((Object)(object)classicStageInfo.monsterDccsPool)) { originalClassicStageInfo.monsterDccsPoolCategories = CopyDccsPoolCategories(classicStageInfo.monsterDccsPool.poolCategories); } if (Object.op_Implicit((Object)(object)classicStageInfo.monsterCategories)) { originalClassicStageInfo.monsterCategories = Object.Instantiate(classicStageInfo.monsterCategories); ((Object)originalClassicStageInfo.monsterCategories).name = ((Object)classicStageInfo.monsterCategories).name; } if (classicStageInfo.possibleMonsterFamilies != null) { originalClassicStageInfo.possibleMonsterFamilies = classicStageInfo.possibleMonsterFamilies.ToList(); } if (Object.op_Implicit((Object)(object)classicStageInfo.interactableDccsPool)) { originalClassicStageInfo.interactableDccsPoolCategories = CopyDccsPoolCategories(classicStageInfo.interactableDccsPool.poolCategories); } if (Object.op_Implicit((Object)(object)classicStageInfo.interactableCategories)) { originalClassicStageInfo.interactableCategories = Object.Instantiate(classicStageInfo.interactableCategories); ((Object)originalClassicStageInfo.interactableCategories).name = ((Object)classicStageInfo.interactableCategories).name; } _classicStageInfoNameToOriginalClassicStageInfos[key] = originalClassicStageInfo; } private static void RestoreClassicStageInfoToOriginalState(ClassicStageInfo classicStageInfo, OriginalClassicStageInfo originalClassicStageInfo) { if (originalClassicStageInfo.monsterDccsPoolCategories != null) { classicStageInfo.monsterDccsPool.poolCategories = CopyDccsPoolCategories(originalClassicStageInfo.monsterDccsPoolCategories).ToArray(); } if (Object.op_Implicit((Object)(object)originalClassicStageInfo.monsterCategories)) { classicStageInfo.monsterCategories = Object.Instantiate(originalClassicStageInfo.monsterCategories); ((Object)classicStageInfo.monsterCategories).name = ((Object)originalClassicStageInfo.monsterCategories).name; } if (originalClassicStageInfo.possibleMonsterFamilies != null) { classicStageInfo.possibleMonsterFamilies = originalClassicStageInfo.possibleMonsterFamilies.ToArray(); } if (originalClassicStageInfo.interactableDccsPoolCategories != null) { classicStageInfo.interactableDccsPool.poolCategories = CopyDccsPoolCategories(originalClassicStageInfo.interactableDccsPoolCategories).ToArray(); } if (Object.op_Implicit((Object)(object)originalClassicStageInfo.interactableCategories)) { classicStageInfo.interactableCategories = Object.Instantiate(originalClassicStageInfo.interactableCategories); ((Object)classicStageInfo.interactableCategories).name = ((Object)originalClassicStageInfo.interactableCategories).name; } } private static List CopyDccsPoolCategories(IEnumerable dccsPoolCategories) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown List list = new List(); foreach (Category dccsPoolCategory in dccsPoolCategories) { Category val = new Category(); val.name = dccsPoolCategory.name; val.categoryWeight = dccsPoolCategory.categoryWeight; val.alwaysIncluded = CopyPoolEntries(dccsPoolCategory.alwaysIncluded).ToArray(); val.includedIfConditionsMet = CopyConditionalPoolEntries(dccsPoolCategory.includedIfConditionsMet).ToArray(); val.includedIfNoConditionsMet = CopyPoolEntries(dccsPoolCategory.includedIfNoConditionsMet).ToArray(); list.Add(val); } return list; } private static List CopyConditionalPoolEntries(IEnumerable poolEntries) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown List list = new List(); foreach (ConditionalPoolEntry poolEntry in poolEntries) { ConditionalPoolEntry val = new ConditionalPoolEntry(); val.requiredExpansions = ArrayUtils.Clone(poolEntry.requiredExpansions); ((PoolEntry)val).weight = ((PoolEntry)poolEntry).weight; ((PoolEntry)val).dccs = Object.Instantiate(((PoolEntry)poolEntry).dccs); ((Object)((PoolEntry)val).dccs).name = ((Object)((PoolEntry)poolEntry).dccs).name; list.Add(val); } return list; } private static List CopyPoolEntries(IEnumerable poolEntries) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown List list = new List(); foreach (PoolEntry poolEntry in poolEntries) { PoolEntry val = new PoolEntry(); val.weight = poolEntry.weight; val.dccs = Object.Instantiate(poolEntry.dccs); ((Object)val.dccs).name = ((Object)poolEntry.dccs).name; list.Add(val); } return list; } private static List GetDirectorCardHoldersFromDCCS(DirectorCardCategorySelection dccs) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_00ad: 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) List list = new List(); if (Object.op_Implicit((Object)(object)dccs)) { Category[] categories = dccs.categories; foreach (Category val in categories) { if (val.cards.Length == 0) { continue; } bool flag = false; flag = IsInteractableDccsCategory(val); DirectorCard[] cards = val.cards; foreach (DirectorCard card in cards) { DirectorCardHolder directorCardHolder = new DirectorCardHolder(); directorCardHolder.Card = card; if (flag) { if ((directorCardHolder.InteractableCategory = Helpers.GetInteractableCategory(val.name)) == InteractableCategory.Custom) { directorCardHolder.CustomInteractableCategory = val.name; } } else if ((directorCardHolder.MonsterCategory = Helpers.GetMonsterCategory(val.name)) == MonsterCategory.Custom) { directorCardHolder.CustomMonsterCategory = val.name; } list.Add(directorCardHolder); } } } return list; } private static bool IsInteractableDccsCategory(Category dccsCategory) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) bool result = false; DirectorCard[] cards = dccsCategory.cards; foreach (DirectorCard val in cards) { if (Object.op_Implicit((Object)(object)val.spawnCard) && Reflection.IsSameOrSubclassOf(((object)val.spawnCard).GetType())) { result = true; break; } } return result; } private static void ApplyNewCardHoldersToDCCS(DirectorCardCategorySelection dccs, List directorCardHolders) { dccs.Clear(); foreach (DirectorCardHolder directorCardHolder in directorCardHolders) { dccs.AddCard(directorCardHolder); } } private static void ApplyInteractableChanges(ClassicStageInfo classicStageInfo, StageInfo stageInfo) { if (DirectorAPI.InteractableActions == null) { return; } Delegate[] invocationList = DirectorAPI.InteractableActions.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(classicStageInfo.interactableDccsPool, stageInfo); } catch (Exception ex) { DirectorPlugin.Logger.LogError((object)ex); } } } private static StageSettings GetStageSettings(ClassicStageInfo classicStageInfo) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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) StageSettings stageSettings = new StageSettings { SceneDirectorInteractableCredits = classicStageInfo.sceneDirectorInteractibleCredits, SceneDirectorMonsterCredits = classicStageInfo.sceneDirectorMonsterCredits, BonusCreditObjects = new Dictionary() }; BonusInteractibleCreditObject[] bonusInteractibleCreditObjects = classicStageInfo.bonusInteractibleCreditObjects; foreach (BonusInteractibleCreditObject val in bonusInteractibleCreditObjects) { if (Object.op_Implicit((Object)(object)val.objectThatGrantsPointsIfEnabled)) { stageSettings.BonusCreditObjects[val.objectThatGrantsPointsIfEnabled] = val.points; } } GetMonsterCategoryWeightsPerDccs(classicStageInfo, stageSettings); GetInteractableCategoryWeightsPerDccs(classicStageInfo, stageSettings); return stageSettings; } private static void InitCustomMixEnemyArtifactDccs() { _dccsMixEnemyArtifact = Object.Instantiate(RoR2Content.mixEnemyMonsterCards); ((Object)_dccsMixEnemyArtifact).name = "dccsR2APIMixEnemyArtifact"; } private static void GetMonsterCategoryWeightsPerDccs(ClassicStageInfo classicStageInfo, StageSettings stageSettings) { stageSettings.MonsterCategoryWeightsPerDccs = new Dictionary>(); GetMonsterCategoryWeights(stageSettings, _dccsMixEnemyArtifact); if (Object.op_Implicit((Object)(object)classicStageInfo.monsterDccsPool)) { Category[] poolCategories = classicStageInfo.monsterDccsPool.poolCategories; foreach (Category val in poolCategories) { GetMonsterCategoryWeights(stageSettings, val.alwaysIncluded); PoolEntry[] includedIfConditionsMet = (PoolEntry[])(object)val.includedIfConditionsMet; GetMonsterCategoryWeights(stageSettings, includedIfConditionsMet); GetMonsterCategoryWeights(stageSettings, val.includedIfNoConditionsMet); } } } private static void GetMonsterCategoryWeights(StageSettings stageSettings, DirectorCardCategorySelection dccs) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0036: Unknown result type (might be due to invalid IL or missing references) stageSettings.MonsterCategoryWeightsPerDccs[dccs] = new Dictionary(); Category[] categories = dccs.categories; foreach (Category val in categories) { stageSettings.MonsterCategoryWeightsPerDccs[dccs][val.name] = val.selectionWeight; } } private static void GetMonsterCategoryWeights(StageSettings stageSettings, PoolEntry[] poolCategories) { foreach (PoolEntry val in poolCategories) { GetMonsterCategoryWeights(stageSettings, val.dccs); } } private static void GetInteractableCategoryWeightsPerDccs(ClassicStageInfo classicStageInfo, StageSettings stageSettings) { stageSettings.InteractableCategoryWeightsPerDccs = new Dictionary>(); if (Object.op_Implicit((Object)(object)classicStageInfo.interactableDccsPool)) { Category[] poolCategories = classicStageInfo.interactableDccsPool.poolCategories; foreach (Category val in poolCategories) { GetInteractableCategoryWeights(stageSettings, val.alwaysIncluded); PoolEntry[] includedIfConditionsMet = (PoolEntry[])(object)val.includedIfConditionsMet; GetInteractableCategoryWeights(stageSettings, includedIfConditionsMet); GetInteractableCategoryWeights(stageSettings, val.includedIfNoConditionsMet); } } } private static void GetInteractableCategoryWeights(StageSettings stageSettings, PoolEntry[] poolCategories) { foreach (PoolEntry val in poolCategories) { GetInteractableCategoryWeights(stageSettings, val.dccs); } } private static void GetInteractableCategoryWeights(StageSettings stageSettings, DirectorCardCategorySelection dccs) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0036: Unknown result type (might be due to invalid IL or missing references) stageSettings.InteractableCategoryWeightsPerDccs[dccs] = new Dictionary(); Category[] categories = dccs.categories; foreach (Category val in categories) { stageSettings.InteractableCategoryWeightsPerDccs[dccs][val.name] = val.selectionWeight; } } private static void SetStageSettings(ClassicStageInfo classicStageInfo, StageSettings stageSettings) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) classicStageInfo.sceneDirectorInteractibleCredits = stageSettings.SceneDirectorInteractableCredits; classicStageInfo.sceneDirectorMonsterCredits = stageSettings.SceneDirectorMonsterCredits; GameObject[] array = stageSettings.BonusCreditObjects.Keys.ToArray(); BonusInteractibleCreditObject[] array2 = (BonusInteractibleCreditObject[])(object)new BonusInteractibleCreditObject[array.Length]; for (int i = 0; i < array.Length; i++) { array2[i] = new BonusInteractibleCreditObject { objectThatGrantsPointsIfEnabled = array[i], points = stageSettings.BonusCreditObjects[array[i]] }; } classicStageInfo.bonusInteractibleCreditObjects = array2; SetMonsterCategoryWeightsPerDccs(classicStageInfo, stageSettings); SetInteractableCategoryWeightsPerDccs(classicStageInfo, stageSettings); } private static void SetMonsterCategoryWeightsPerDccs(ClassicStageInfo classicStageInfo, StageSettings stageSettings) { SetMonsterCategoryWeights(_dccsMixEnemyArtifact, stageSettings.MonsterCategoryWeightsPerDccs[_dccsMixEnemyArtifact]); if (Object.op_Implicit((Object)(object)classicStageInfo.monsterDccsPool)) { Category[] poolCategories = classicStageInfo.monsterDccsPool.poolCategories; foreach (Category val in poolCategories) { SetMonsterCategoryWeights(stageSettings, val.alwaysIncluded); PoolEntry[] includedIfConditionsMet = (PoolEntry[])(object)val.includedIfConditionsMet; SetMonsterCategoryWeights(stageSettings, includedIfConditionsMet); SetMonsterCategoryWeights(stageSettings, val.includedIfNoConditionsMet); } } } private static void SetMonsterCategoryWeights(DirectorCardCategorySelection dccs, Dictionary newMonsterCategoryWeights) { //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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) for (int i = 0; i < dccs.categories.Length; i++) { Category val = dccs.categories[i]; string name = val.name; val.selectionWeight = newMonsterCategoryWeights[name]; dccs.categories[i] = val; } } private static void SetMonsterCategoryWeights(StageSettings stageSettings, PoolEntry[] poolCategories) { foreach (PoolEntry val in poolCategories) { SetMonsterCategoryWeights(val.dccs, stageSettings.MonsterCategoryWeightsPerDccs[val.dccs]); } } private static void SetInteractableCategoryWeightsPerDccs(ClassicStageInfo classicStageInfo, StageSettings stageSettings) { if (Object.op_Implicit((Object)(object)classicStageInfo.interactableDccsPool)) { Category[] poolCategories = classicStageInfo.interactableDccsPool.poolCategories; foreach (Category val in poolCategories) { SetInteractableCategoryWeights(stageSettings, val.alwaysIncluded); PoolEntry[] includedIfConditionsMet = (PoolEntry[])(object)val.includedIfConditionsMet; SetInteractableCategoryWeights(stageSettings, includedIfConditionsMet); SetInteractableCategoryWeights(stageSettings, val.includedIfNoConditionsMet); } } } private static void SetInteractableCategoryWeights(StageSettings stageSettings, PoolEntry[] poolCategories) { foreach (PoolEntry val in poolCategories) { SetInteractableCategoryWeights(val.dccs, stageSettings.InteractableCategoryWeightsPerDccs[val.dccs]); } } private static void SetInteractableCategoryWeights(DirectorCardCategorySelection dccs, Dictionary newInteractableCategoryWeights) { //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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < dccs.categories.Length; i++) { Category val = dccs.categories[i]; val.selectionWeight = newInteractableCategoryWeights[val.name]; dccs.categories[i] = val; } } private static bool IsStageCombatDirectorInternal(CombatDirector combatDirector) { return _currentStageCombatDirectorsHashSet.Contains(combatDirector); } } [BepInPlugin("com.bepis.r2api.director", "R2API.Director", "3.1.0")] public sealed class DirectorPlugin : BaseUnityPlugin { internal static ManualLogSource Logger { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; DirectorAPI.SetHooks(); SpawnCardCloningAPI.SetHooks(); } private void OnEnable() { DirectorAPI.SetHooks(); SpawnCardCloningAPI.SetHooks(); } private void OnDisable() { DirectorAPI.UnsetHooks(); SpawnCardCloningAPI.UnsetHooks(); } } public class RunCombatDirectorsFixedUpdate : MonoBehaviour { public CombatDirector[] combatDirectors; public void Awake() { DirectorAPI._currentStageCombatDirectorsHashSet.Clear(); combatDirectors = ((Component)this).GetComponents(); if (combatDirectors != null) { CombatDirector[] array = combatDirectors; foreach (CombatDirector item in array) { DirectorAPI._currentStageCombatDirectorsHashSet.Add(item); } } } public void FixedUpdate() { if (combatDirectors == null) { return; } for (int i = 0; i < DirectorAPI._allCombatDirectors.Count; i++) { CombatDirector val = DirectorAPI._allCombatDirectors[i]; if (!Object.op_Implicit((Object)(object)val)) { DirectorAPI._allCombatDirectors.RemoveAt(i); } else if (DirectorAPI.HandleCombatDirectorActivity(val)) { val.FixedUpdate(); } } } } } namespace R2API.AutoVersionGen { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] internal class AutoVersionAttribute : Attribute { } } namespace R2API.SpawnCardCloning { public abstract class BaseSpawnCardClone : ScriptableObject where T : SpawnCard { public delegate bool CustomCondition(RebuildCardsInfo rebuildCardsInfo); public delegate void OnSpawnCardCloneAdded(RebuildCardsInfo rebuildCardsInfo); public enum CloningType { SpawnCard, Prefab, Prefabs } [Header("Base For Cloning")] [Tooltip("If set to SpawnCard, it will try to match it directly for cloning. If set to Prefab, it will match spawncards with target prefab for cloning. If set to Prefabs, MultiCharacterSpawnCardClone will match spawncards with target prefabs")] public CloningType cloningType; [Tooltip("SpawnCard to use for matching")] public AddressReferencedSpawnCard targetSpawnCard; [Tooltip("Set Spawn Card to return instead of cloned Spawn Cards")] public AddressReferencedSpawnCard overrideReturnSpawnCard; [Tooltip("Prefab to use for matching the spawn card to clone")] public AddressReferencedPrefab targetPrefab; [Tooltip("Prefab to override the original prefab of the cloned Spawn Card")] public AddressReferencedPrefab prefab; [Tooltip("Override to which category cloned Spawn Card will go. Array incase if expected category name in some stage is slightly different than others. Breaks on first match")] public string[] overrideCategory = Array.Empty(); [Header("Cloning DirectorCard Settings")] public float selectionWeightMultiplier = 1f; public bool overrideSelectionWeight; public int selectionWeight; public bool overrideSpawnDistance; public MonsterSpawnDistance spawnDistance; public bool overridePreventOverhead; public bool preventOverhead; public float minimumStageCompletionsMultiplier = 1f; public bool overrideMinimumStageCompletions; public int minimumStageCompletions; public bool overrideRequiredUnlockableDef; public AddressReferencedUnlockableDef requiredUnlockableDef; public bool overrideForbiddenUnlockableDef; public AddressReferencedUnlockableDef forbiddenUnlockableDef; [Header("Cloning SpawnCard Settings")] public float costMultiplier = 1f; public bool overrideCost; public int cost; public bool overrideHullSize; public HullClassification hullSize; public bool overrideNodeGraphType; public GraphType nodeGrapthType; public bool overrideRequiredFlags; [EnumMask(typeof(NodeFlags))] public NodeFlags requiredFlags; public bool overrideForbiddenFlags; [EnumMask(typeof(NodeFlags))] public NodeFlags forbiddenFlags; public bool overrideEliteRules; [Tooltip("Default = default rules, ArtifactOnly = only elite when forced by the elite-only artifact, Lunar = special lunar elites only (+ regular w/ elite-only artifact)")] public EliteRules eliteRules; public CustomCondition customCondition; public OnSpawnCardCloneAdded onSpawnCardCloneAdded; private Dictionary spawnCardOriginalToCloned = new Dictionary(); private Dictionary directorCardOriginalToCloned = new Dictionary(); public virtual DirectorCard GetDirectorCard(DirectorCard originalDirectorCard) { //IL_0013: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown if (!directorCardOriginalToCloned.TryGetValue(originalDirectorCard, out DirectorCard value)) { value = new DirectorCard { selectionWeight = (overrideSelectionWeight ? selectionWeight : ((int)((float)originalDirectorCard.selectionWeight * selectionWeightMultiplier))), spawnDistance = (overrideSpawnDistance ? spawnDistance : originalDirectorCard.spawnDistance), preventOverhead = (overridePreventOverhead ? preventOverhead : originalDirectorCard.preventOverhead), minimumStageCompletions = (overrideMinimumStageCompletions ? minimumStageCompletions : ((int)((float)originalDirectorCard.minimumStageCompletions * minimumStageCompletionsMultiplier))), requiredUnlockableDef = (overrideRequiredUnlockableDef ? ((AddressReferencedAsset)(object)requiredUnlockableDef).Asset : originalDirectorCard.requiredUnlockableDef), forbiddenUnlockableDef = (overrideForbiddenUnlockableDef ? ((AddressReferencedAsset)(object)forbiddenUnlockableDef).Asset : originalDirectorCard.forbiddenUnlockableDef) }; directorCardOriginalToCloned.Add(originalDirectorCard, value); } return value; } public virtual T GetSpawnCard(T originalSpawnCard) { if (Object.op_Implicit((Object)(object)((AddressReferencedAsset)(object)overrideReturnSpawnCard).Asset)) { SpawnCard asset = ((AddressReferencedAsset)(object)overrideReturnSpawnCard).Asset; T val = (T)(object)((asset is T) ? asset : null); if (val != null) { return val; } } if (spawnCardOriginalToCloned.TryGetValue(originalSpawnCard, out var value)) { return value; } value = ScriptableObject.CreateInstance(); ((SpawnCard)value).prefab = ((AddressReferencedAsset)(object)prefab).Asset; ((Object)(object)value).name = ((Object)this).name; UpdateValuesForClonedSpawnCard(originalSpawnCard, value); return value; } public virtual void Register() { if (!SpawnCardCloningAPI.allSpawnCardClones.Contains(this)) { SpawnCardCloningAPI.allSpawnCardClones.Add(this); } if (cloningType == CloningType.SpawnCard) { SpawnCard asset = ((AddressReferencedAsset)(object)targetSpawnCard).Asset; if (Object.op_Implicit((Object)(object)asset)) { if (SpawnCardCloningAPI.spawnCardClonesFromOriginalSpawnCard.TryGetValue(asset, out List value) && !value.Contains(this)) { value.Add(this); } else { SpawnCardCloningAPI.spawnCardClonesFromOriginalSpawnCard.Add(asset, new List(1) { this }); } } } if (cloningType != CloningType.Prefab) { return; } GameObject asset2 = ((AddressReferencedAsset)(object)targetPrefab).Asset; if (Object.op_Implicit((Object)(object)asset2)) { if (SpawnCardCloningAPI.spawnCardClonesFromPrefab.TryGetValue(asset2, out List value2) && !value2.Contains(this)) { value2.Add(this); return; } SpawnCardCloningAPI.spawnCardClonesFromPrefab.Add(asset2, new List(1) { this }); } } public virtual void Unregister() { if (SpawnCardCloningAPI.allSpawnCardClones.Contains(this)) { SpawnCardCloningAPI.allSpawnCardClones.Remove(this); } SpawnCard asset = ((AddressReferencedAsset)(object)targetSpawnCard).Asset; if (Object.op_Implicit((Object)(object)asset) && SpawnCardCloningAPI.spawnCardClonesFromOriginalSpawnCard.TryGetValue(asset, out List value) && value.Contains(this)) { value.Remove(this); } GameObject asset2 = ((AddressReferencedAsset)(object)targetPrefab).Asset; if (Object.op_Implicit((Object)(object)asset2) && SpawnCardCloningAPI.spawnCardClonesFromPrefab.TryGetValue(asset2, out List value2) && value2.Contains(this)) { value2.Remove(this); } } public virtual void UpdateValuesForClonedSpawnCards() { foreach (KeyValuePair item in spawnCardOriginalToCloned) { T key = item.Key; T value = item.Value; if (Object.op_Implicit((Object)(object)key) && Object.op_Implicit((Object)(object)value)) { UpdateValuesForClonedSpawnCard(key, value); } } } public virtual void UpdateValuesForClonedSpawnCard(T originalSpawnCard, T clonedSpawnCard) { //IL_004b: 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_0050: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) ((SpawnCard)clonedSpawnCard).directorCreditCost = (overrideCost ? cost : ((int)((float)((SpawnCard)originalSpawnCard).directorCreditCost * costMultiplier))); ((SpawnCard)clonedSpawnCard).eliteRules = (overrideEliteRules ? eliteRules : ((SpawnCard)originalSpawnCard).eliteRules); ((SpawnCard)clonedSpawnCard).requiredFlags = (overrideRequiredFlags ? requiredFlags : ((SpawnCard)originalSpawnCard).requiredFlags); ((SpawnCard)clonedSpawnCard).hullSize = (overrideHullSize ? hullSize : ((SpawnCard)originalSpawnCard).hullSize); ((SpawnCard)clonedSpawnCard).nodeGraphType = (overrideNodeGraphType ? nodeGrapthType : ((SpawnCard)originalSpawnCard).nodeGraphType); ((SpawnCard)clonedSpawnCard).forbiddenFlags = (overrideForbiddenFlags ? forbiddenFlags : ((SpawnCard)originalSpawnCard).forbiddenFlags); } } [CreateAssetMenu(fileName = "New CharacterSpawnCardClone", menuName = "R2API/DirectorAPI/SpawnCardCloning/CharacterSpawnCardClone")] public class CharacterSpawnCardClone : BaseSpawnCardClone { [Header("Cloning CharacterSpawnCard Settings")] public bool overrideNoElites; public bool noElites; public bool overrideForbiddenAsBoss; public bool forbiddenAsBoss; [CanBeNull] [Tooltip("The loadout for any summoned character to use.")] public SerializableLoadout loadout; public bool overrideEquipmentToGrant; [Tooltip("The set of equipment to grant to any summoned character, after inventory copy.")] [NotNull] public EquipmentDef[] equipmentToGrant = Array.Empty(); public bool overrideItemsToGrant; [NotNull] [Tooltip("The set of items to grant to any summoned character, after inventory copy.")] public ItemCountPair[] itemsToGrant = Array.Empty(); public override void UpdateValuesForClonedSpawnCard(CharacterSpawnCard originalSpawnCard, CharacterSpawnCard clonedSpawnCard) { base.UpdateValuesForClonedSpawnCard(originalSpawnCard, clonedSpawnCard); clonedSpawnCard.forbiddenAsBoss = (overrideForbiddenAsBoss ? forbiddenAsBoss : originalSpawnCard.forbiddenAsBoss); clonedSpawnCard.noElites = (overrideNoElites ? noElites : originalSpawnCard.noElites); clonedSpawnCard.equipmentToGrant = (EquipmentDef[])(overrideEquipmentToGrant ? ((Array)equipmentToGrant) : ((Array)originalSpawnCard.equipmentToGrant)); clonedSpawnCard.itemsToGrant = (overrideItemsToGrant ? itemsToGrant : originalSpawnCard.itemsToGrant); } } public class GameObjectArrayComparer : IEqualityComparer { public bool Equals(GameObject[] x, GameObject[] y) { if (x == y) { return true; } if (x == null || y == null || x.Length != y.Length) { return false; } for (int i = 0; i < x.Length; i++) { if ((Object)(object)x[i] != (Object)(object)y[i]) { return false; } } return true; } public int GetHashCode(GameObject[] obj) { if (obj == null) { return 0; } int num = 17; foreach (GameObject val in obj) { num = num * 31 + (((Object)(object)val != (Object)null) ? ((object)val).GetHashCode() : 0); } return num; } } public class GameObjectArrayDictionary { private class Entry { public GameObject[] gameObjects; public T t; public Entry(GameObject[] gameObjects, T t) { this.gameObjects = gameObjects; this.t = t; } } private List _entries = new List(); public void Add(GameObject[] keys, T t) { if (keys != null) { _entries.Add(new Entry(keys, t)); } } public bool Remove(GameObject[] gameObjects, bool matchOrder, bool removeAllMatches = false) { if (gameObjects == null) { return false; } if (removeAllMatches) { return _entries.RemoveAll((Entry entry) => Match(entry.gameObjects, gameObjects, matchOrder)) > 0; } for (int num = 0; num < _entries.Count; num++) { if (Match(_entries[num].gameObjects, gameObjects, matchOrder)) { _entries.RemoveAt(num); return true; } } return false; } public void Clear() { _entries.Clear(); } public bool ContainsKey(GameObject[] gameObjects, bool matchOrder) { foreach (Entry entry in _entries) { if (Match(entry.gameObjects, gameObjects, matchOrder)) { return true; } } return false; } public bool TryGetValue(GameObject[] gameObjects, bool matchOrder, out T t) { foreach (Entry entry in _entries) { if (Match(entry.gameObjects, gameObjects, matchOrder)) { t = entry.t; return true; } } t = default(T); return false; } private bool Match(GameObject[] entryGameObjects, GameObject[] inputGameObjects, bool matchOrder) { if (entryGameObjects == null || inputGameObjects == null || entryGameObjects.Length != inputGameObjects.Length) { return false; } if (matchOrder) { for (int i = 0; i < entryGameObjects.Length; i++) { if ((Object)(object)entryGameObjects[i] != (Object)(object)inputGameObjects[i]) { return false; } } return true; } IOrderedEnumerable first = from go in entryGameObjects select ((Object)(object)go != (Object)null) ? ((Object)go).GetInstanceID() : 0 into id orderby id select id; IOrderedEnumerable second = from go in inputGameObjects select ((Object)(object)go != (Object)null) ? ((Object)go).GetInstanceID() : 0 into id orderby id select id; return first.SequenceEqual(second); } } [CreateAssetMenu(fileName = "New InteractableSpawnCardClone", menuName = "R2API/DirectorAPI/SpawnCardCloning/InteractableSpawnCardClone")] public class InteractableSpawnCardClone : BaseSpawnCardClone { [Header("Cloning InteractableSpawnCard Settings")] public bool overrideOrientToFloor; [Tooltip("Whether or not to orient the object to the normal of the ground it spawns on.")] public bool orientToFloor; public bool overrideSlightlyRandomizeOrientation; public bool slightlyRandomizeOrientation; public bool overrideSkipSpawnWhenSacrificeArtifactEnabled; public bool skipSpawnWhenSacrificeArtifactEnabled; public float weightScalarWhenSacrificeArtifactEnabledMultiplier = 1f; public bool overrideWeightScalarWhenSacrificeArtifactEnabled; [Tooltip("When Sacrifice is enabled, this is multiplied by the card's weight")] public float weightScalarWhenSacrificeArtifactEnabled = 1f; public bool overrideSkipSpawnWhenDevotionArtifactEnabled; public float maxSpawnsPerStageMultiplier = 1f; public bool skipSpawnWhenDevotionArtifactEnabled; public bool overrideMaxSpawnsPerStage; [Tooltip("Won't spawn more than this many per stage. If it's negative, there's no cap")] public int maxSpawnsPerStage = -1; public float prismaticTrialSpawnChanceMultiplier = 1f; public bool overridePrismaticTrialSpawnChance; [Range(0f, 1f)] [Tooltip("When playing Primatic Trials, this interactable will have a required check to see if it is supposed to spawn. 0 is will not spawn, 1 will 100% spawn and will be default.")] public float prismaticTrialSpawnChance = 1f; public override void UpdateValuesForClonedSpawnCard(InteractableSpawnCard originalSpawnCard, InteractableSpawnCard clonedInteractableSpawnCard) { base.UpdateValuesForClonedSpawnCard(originalSpawnCard, clonedInteractableSpawnCard); clonedInteractableSpawnCard.orientToFloor = (overrideOrientToFloor ? orientToFloor : originalSpawnCard.orientToFloor); clonedInteractableSpawnCard.slightlyRandomizeOrientation = (overrideSlightlyRandomizeOrientation ? slightlyRandomizeOrientation : originalSpawnCard.slightlyRandomizeOrientation); clonedInteractableSpawnCard.skipSpawnWhenSacrificeArtifactEnabled = (overrideSkipSpawnWhenSacrificeArtifactEnabled ? skipSpawnWhenSacrificeArtifactEnabled : originalSpawnCard.skipSpawnWhenSacrificeArtifactEnabled); clonedInteractableSpawnCard.weightScalarWhenSacrificeArtifactEnabled = (overrideWeightScalarWhenSacrificeArtifactEnabled ? weightScalarWhenSacrificeArtifactEnabled : (originalSpawnCard.weightScalarWhenSacrificeArtifactEnabled * weightScalarWhenSacrificeArtifactEnabledMultiplier)); clonedInteractableSpawnCard.skipSpawnWhenDevotionArtifactEnabled = (overrideSkipSpawnWhenDevotionArtifactEnabled ? skipSpawnWhenDevotionArtifactEnabled : originalSpawnCard.skipSpawnWhenDevotionArtifactEnabled); clonedInteractableSpawnCard.maxSpawnsPerStage = (overrideMaxSpawnsPerStage ? maxSpawnsPerStage : ((int)((float)originalSpawnCard.maxSpawnsPerStage * maxSpawnsPerStageMultiplier))); clonedInteractableSpawnCard.prismaticTrialSpawnChance = (overridePrismaticTrialSpawnChance ? prismaticTrialSpawnChanceMultiplier : (originalSpawnCard.prismaticTrialSpawnChance * prismaticTrialSpawnChanceMultiplier)); } } [CreateAssetMenu(fileName = "New MultiCharacterSpawnCardClone", menuName = "R2API/DirectorAPI/SpawnCardCloning/MultiCharacterSpawnCardClone")] internal class MultiCharacterSpawnCardClone : BaseSpawnCardClone { [Header("Base For Cloning")] [Tooltip("Master prefabs to use for finding the spawn card to clone")] public AddressReferencedPrefab[] targetMasterPrefabs; [Tooltip("If set to true, prefab order is respected. Otherwise order doesn't matter")] public bool matchOrder; [Tooltip("Master prefabs to override the original master prefabs of the spawn card")] public AddressReferencedPrefab[] masterPrefabs; [Header("Cloning CharacterSpawnCard Settings")] public bool overrideNoElites; public bool noElites; public bool overrideForbiddenAsBoss; public bool forbiddenAsBoss; [CanBeNull] [Tooltip("The loadout for any summoned character to use.")] public SerializableLoadout loadout; public bool overrideEquipmentToGrant; [Tooltip("The set of equipment to grant to any summoned character, after inventory copy.")] [NotNull] public EquipmentDef[] equipmentToGrant = Array.Empty(); public bool overrideItemsToGrant; [NotNull] [Tooltip("The set of items to grant to any summoned character, after inventory copy.")] public ItemCountPair[] itemsToGrant = Array.Empty(); public override void UpdateValuesForClonedSpawnCard(MultiCharacterSpawnCard originalSpawnCard, MultiCharacterSpawnCard clonedMultiCharacterSpawnCard) { base.UpdateValuesForClonedSpawnCard(originalSpawnCard, clonedMultiCharacterSpawnCard); List list = new List(); AddressReferencedPrefab[] array = masterPrefabs; foreach (AddressReferencedPrefab val in array) { list.Add(((AddressReferencedAsset)(object)val).Asset); } clonedMultiCharacterSpawnCard.masterPrefabs = list.ToArray(); ((CharacterSpawnCard)clonedMultiCharacterSpawnCard).forbiddenAsBoss = (overrideForbiddenAsBoss ? forbiddenAsBoss : ((CharacterSpawnCard)originalSpawnCard).forbiddenAsBoss); ((CharacterSpawnCard)clonedMultiCharacterSpawnCard).noElites = (overrideNoElites ? noElites : ((CharacterSpawnCard)originalSpawnCard).noElites); ((CharacterSpawnCard)clonedMultiCharacterSpawnCard).equipmentToGrant = (EquipmentDef[])(overrideEquipmentToGrant ? ((Array)equipmentToGrant) : ((Array)((CharacterSpawnCard)originalSpawnCard).equipmentToGrant)); ((CharacterSpawnCard)clonedMultiCharacterSpawnCard).itemsToGrant = (overrideItemsToGrant ? itemsToGrant : ((CharacterSpawnCard)originalSpawnCard).itemsToGrant); } public override void Register() { base.Register(); if (cloningType != CloningType.Prefabs) { return; } GameObject[] array = GetTargetMasterPrefabs(); if (array.Length != 0) { if (SpawnCardCloningAPI.multiCharacterSpawnCardClonesFromPrefab.TryGetValue(array, matchOrder, out List t) && !t.Contains(this)) { t.Add(this); return; } SpawnCardCloningAPI.multiCharacterSpawnCardClonesFromPrefab.Add(array, new List(1) { this }); } } public override void Unregister() { base.Unregister(); GameObject[] array = GetTargetMasterPrefabs(); if (array.Length != 0 && SpawnCardCloningAPI.multiCharacterSpawnCardClonesFromPrefab.TryGetValue(array, matchOrder, out List t) && t.Contains(this)) { t.Remove(this); } } public GameObject[] GetTargetMasterPrefabs() { List list = new List(); AddressReferencedPrefab[] array = targetMasterPrefabs; for (int i = 0; i < array.Length; i++) { GameObject asset = ((AddressReferencedAsset)(object)array[i]).Asset; list.Add(asset); } return list.ToArray(); } public GameObject[] GetMasterPrefabs() { List list = new List(); AddressReferencedPrefab[] array = masterPrefabs; for (int i = 0; i < array.Length; i++) { GameObject asset = ((AddressReferencedAsset)(object)array[i]).Asset; list.Add(asset); } return list.ToArray(); } } public struct RebuildCardsInfo { public ClassicStageInfo classicStageInfo; public DirectorCardCategorySelection forcedMonsterCategory; public DirectorCardCategorySelection forcedInteractableCategory; public DccsPool dccsPool; public Category[] categories; public PoolEntry poolEntry; public DirectorCardCategorySelection directorCardCategorySelection; public Category dccsPoolCategory; public Category category; public DirectorCard directorCard; public SpawnCard spawnCard; public object spawnCardClone; public DirectorCard clonedDirectorCard; public SpawnCard clonedSpawnCard; } [CreateAssetMenu(fileName = "New SpawnCardClone", menuName = "R2API/DirectorAPI/SpawnCardCloning/SpawnCardClone")] public class SpawnCardClone : BaseSpawnCardClone { } public static class SpawnCardCloningAPI { [CompilerGenerated] private static class <>O { public static hook_RebuildCards <0>__ClassicStageInfo_RebuildCards; } internal static List allSpawnCardClones = new List(); internal static Dictionary> spawnCardClonesFromOriginalSpawnCard = new Dictionary>(); internal static Dictionary> spawnCardClonesFromPrefab = new Dictionary>(); internal static GameObjectArrayDictionary> multiCharacterSpawnCardClonesFromPrefab = new GameObjectArrayDictionary>(); private static bool handledMixEnemyMonsterCards; internal static void SetHooks() { //IL_0010: 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) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__ClassicStageInfo_RebuildCards; if (obj == null) { hook_RebuildCards val = ClassicStageInfo_RebuildCards; <>O.<0>__ClassicStageInfo_RebuildCards = val; obj = (object)val; } ClassicStageInfo.RebuildCards += (hook_RebuildCards)obj; } internal static void UnsetHooks() { //IL_0010: 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) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__ClassicStageInfo_RebuildCards; if (obj == null) { hook_RebuildCards val = ClassicStageInfo_RebuildCards; <>O.<0>__ClassicStageInfo_RebuildCards = val; obj = (object)val; } ClassicStageInfo.RebuildCards -= (hook_RebuildCards)obj; } private static void ClassicStageInfo_RebuildCards(orig_RebuildCards orig, ClassicStageInfo self, DirectorCardCategorySelection forcedMonsterCategory, DirectorCardCategorySelection forcedInteractableCategory) { RebuildCardsInfo rebuildCardsInfo = new RebuildCardsInfo { classicStageInfo = self, forcedInteractableCategory = forcedInteractableCategory, forcedMonsterCategory = forcedMonsterCategory }; if (!handledMixEnemyMonsterCards) { HandleDirectorCardCategorySelection(RoR2Content.mixEnemyMonsterCards, rebuildCardsInfo); handledMixEnemyMonsterCards = true; } HandlDccsPool(self.monsterDccsPool, rebuildCardsInfo); HandlDccsPool(self.interactableDccsPool, rebuildCardsInfo); orig.Invoke(self, forcedMonsterCategory, forcedInteractableCategory); } private static void HandlDccsPool(DccsPool dccsPool, RebuildCardsInfo rebuildCardsInfo) { if (Object.op_Implicit((Object)(object)dccsPool)) { rebuildCardsInfo.dccsPool = dccsPool; HandlePoolCategories(dccsPool.poolCategories, rebuildCardsInfo); } } private static void HandlePoolCategories(Category[] categories, RebuildCardsInfo rebuildCardsInfo) { if (categories == null) { return; } rebuildCardsInfo.categories = categories; foreach (Category val in categories) { if (val == null) { break; } rebuildCardsInfo.dccsPoolCategory = val; PoolEntry[] alwaysIncluded = val.alwaysIncluded; for (int j = 0; j < alwaysIncluded.Length; j++) { HandlePoolEntry(alwaysIncluded[j], rebuildCardsInfo); } ConditionalPoolEntry[] includedIfConditionsMet = val.includedIfConditionsMet; for (int j = 0; j < includedIfConditionsMet.Length; j++) { HandlePoolEntry((PoolEntry)(object)includedIfConditionsMet[j], rebuildCardsInfo); } alwaysIncluded = val.includedIfNoConditionsMet; for (int j = 0; j < alwaysIncluded.Length; j++) { HandlePoolEntry(alwaysIncluded[j], rebuildCardsInfo); } } } private static void HandlePoolEntry(PoolEntry poolEntry, RebuildCardsInfo rebuildCardsInfo) { if (poolEntry != null) { rebuildCardsInfo.poolEntry = poolEntry; HandleDirectorCardCategorySelection(poolEntry.dccs, rebuildCardsInfo); } } private static void HandleDirectorCardCategorySelection(DirectorCardCategorySelection directorCardCategorySelection, RebuildCardsInfo rebuildCardsInfo) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)directorCardCategorySelection) || directorCardCategorySelection.categories == null || directorCardCategorySelection.categories.Length == 0) { return; } rebuildCardsInfo.directorCardCategorySelection = directorCardCategorySelection; Dictionary dictionary = new Dictionary(); HashSet hashSet = new HashSet(); Category[] categories = directorCardCategorySelection.categories; foreach (Category val in categories) { if (!Utility.IsNullOrWhiteSpace(val.name) && !hashSet.Contains(val.name)) { hashSet.Add(val.name); } } for (int j = 0; j < directorCardCategorySelection.categories.Length; j++) { ref Category reference = ref directorCardCategorySelection.categories[j]; ref DirectorCard[] cards = ref reference.cards; if (cards == null || cards.Length == 0) { continue; } rebuildCardsInfo.category = reference; HashSet appliedClonedSpawnCardPrefabs = new HashSet(); HashSet appliedClonedSpawnCardPrefabs2 = new HashSet(new GameObjectArrayComparer()); DirectorCard[] array = cards; foreach (DirectorCard val2 in array) { if (val2 == null) { continue; } rebuildCardsInfo.directorCard = val2; SpawnCard val3 = (rebuildCardsInfo.spawnCard = val2.spawnCard); if (!Object.op_Implicit((Object)(object)val3) && val2.spawnCardReference != null) { val3 = (SpawnCard)(Object.op_Implicit(((AssetReference)val2.spawnCardReference).Asset) ? ((object)/*isinst with value type is only supported in some contexts*/) : ((object)((AssetReference)val2.spawnCardReference).LoadAssetAsync().WaitForCompletion())); } if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val3.prefab)) { CharacterSpawnCard val4 = (CharacterSpawnCard)(object)((val3 is CharacterSpawnCard) ? val3 : null); if (val4 != null) { HandleSpawnCard(ref reference, appliedClonedSpawnCardPrefabs, val2, val4, dictionary, hashSet, rebuildCardsInfo); } InteractableSpawnCard val5 = (InteractableSpawnCard)(object)((val3 is InteractableSpawnCard) ? val3 : null); if (val5 != null) { HandleSpawnCard(ref reference, appliedClonedSpawnCardPrefabs, val2, val5, dictionary, hashSet, rebuildCardsInfo); } MultiCharacterSpawnCard val6 = (MultiCharacterSpawnCard)(object)((val3 is MultiCharacterSpawnCard) ? val3 : null); if (val6 != null && !HandleMultiCharacterSpawnCard(ref reference, appliedClonedSpawnCardPrefabs2, val2, val6, dictionary, hashSet, rebuildCardsInfo)) { HandleSpawnCard(ref reference, appliedClonedSpawnCardPrefabs, val2, val6, dictionary, hashSet, rebuildCardsInfo); } } } } foreach (KeyValuePair item in dictionary) { DirectorCard key = item.Key; if (key == null) { continue; } for (int k = 0; k < directorCardCategorySelection.categories.Length; k++) { ref Category reference2 = ref directorCardCategorySelection.categories[k]; if (reference2.name == item.Value && !reference2.cards.Contains(key)) { int num = reference2.cards.Length; Array.Resize(ref reference2.cards, num + 1); reference2.cards[num] = key; break; } } } } private static void HandleSpawnCard(ref Category category, HashSet appliedClonedSpawnCardPrefabs, DirectorCard directorCard, T2 spawnCard, Dictionary overrideCategories, HashSet validCategories, RebuildCardsInfo rebuildCardsInfo) where T1 : BaseSpawnCardClone where T2 : SpawnCard { if ((!spawnCardClonesFromPrefab.TryGetValue(((SpawnCard)spawnCard).prefab, out List value) && !spawnCardClonesFromOriginalSpawnCard.TryGetValue((SpawnCard)(object)spawnCard, out value)) || value == null || value.Count == 0) { return; } foreach (object item in value) { if (!((rebuildCardsInfo.spawnCardClone = item) is T1 val) || appliedClonedSpawnCardPrefabs.Contains(AddressReferencedPrefab.op_Implicit(val.prefab))) { continue; } appliedClonedSpawnCardPrefabs.Add(AddressReferencedPrefab.op_Implicit(val.prefab)); DirectorCard directorCard2 = val.GetDirectorCard(directorCard); directorCard2.spawnCard = (SpawnCard)(object)val.GetSpawnCard(spawnCard); rebuildCardsInfo.clonedDirectorCard = directorCard2; rebuildCardsInfo.clonedSpawnCard = directorCard2.spawnCard; if (val.customCondition != null && !val.customCondition(rebuildCardsInfo)) { continue; } val.onSpawnCardCloneAdded?.Invoke(rebuildCardsInfo); if (val.overrideCategory != null && val.overrideCategory.Length != 0) { string[] overrideCategory = val.overrideCategory; foreach (string text in overrideCategory) { if (validCategories.Contains(text)) { overrideCategories.Add(directorCard2, text); break; } } } else if (!category.cards.Contains(directorCard2)) { int num = category.cards.Length; Array.Resize(ref category.cards, num + 1); category.cards[num] = directorCard2; } } } private static bool HandleMultiCharacterSpawnCard(ref Category category, HashSet appliedClonedSpawnCardPrefabs, DirectorCard directorCard, MultiCharacterSpawnCard spawnCard, Dictionary overrideCategories, HashSet validCategories, RebuildCardsInfo rebuildCardsInfo) { if (multiCharacterSpawnCardClonesFromPrefab.TryGetValue(spawnCard.masterPrefabs, matchOrder: false, out List t)) { if (t == null || t.Count == 0) { return false; } foreach (object item in t) { if (!((rebuildCardsInfo.spawnCardClone = item) is MultiCharacterSpawnCardClone multiCharacterSpawnCardClone)) { continue; } GameObject[] masterPrefabs = multiCharacterSpawnCardClone.GetMasterPrefabs(); if (appliedClonedSpawnCardPrefabs.Contains(masterPrefabs)) { continue; } appliedClonedSpawnCardPrefabs.Add(masterPrefabs); DirectorCard directorCard2 = multiCharacterSpawnCardClone.GetDirectorCard(directorCard); directorCard2.spawnCard = (SpawnCard)(object)multiCharacterSpawnCardClone.GetSpawnCard(spawnCard); rebuildCardsInfo.clonedDirectorCard = directorCard2; rebuildCardsInfo.clonedSpawnCard = directorCard2.spawnCard; if (multiCharacterSpawnCardClone.customCondition != null && !multiCharacterSpawnCardClone.customCondition(rebuildCardsInfo)) { continue; } multiCharacterSpawnCardClone.onSpawnCardCloneAdded?.Invoke(rebuildCardsInfo); if (multiCharacterSpawnCardClone.overrideCategory != null && multiCharacterSpawnCardClone.overrideCategory.Length != 0) { string[] overrideCategory = multiCharacterSpawnCardClone.overrideCategory; foreach (string text in overrideCategory) { if (validCategories.Contains(text)) { overrideCategories.Add(directorCard2, text); break; } } } else if (!category.cards.Contains(directorCard2)) { int num = category.cards.Length; Array.Resize(ref category.cards, num + 1); category.cards[num] = directorCard2; } } return true; } return false; } } } namespace R2API.AddressReferencedAssets { [Serializable] public class AddressReferencedFamilyDirectorCardCategorySelection : AddressReferencedAsset { public static implicit operator bool(AddressReferencedFamilyDirectorCardCategorySelection addressReferencedAsset) { return Object.op_Implicit((Object)(object)((AddressReferencedAsset)(object)addressReferencedAsset)?.Asset); } public static implicit operator FamilyDirectorCardCategorySelection(AddressReferencedFamilyDirectorCardCategorySelection addressReferencedAsset) { return ((AddressReferencedAsset)(object)addressReferencedAsset)?.Asset; } public static implicit operator AddressReferencedFamilyDirectorCardCategorySelection(string address) { return new AddressReferencedFamilyDirectorCardCategorySelection(address); } public static implicit operator AddressReferencedFamilyDirectorCardCategorySelection(FamilyDirectorCardCategorySelection asset) { return new AddressReferencedFamilyDirectorCardCategorySelection(asset); } public AddressReferencedFamilyDirectorCardCategorySelection() { } public AddressReferencedFamilyDirectorCardCategorySelection(FamilyDirectorCardCategorySelection gameObject) : base(gameObject) { } public AddressReferencedFamilyDirectorCardCategorySelection(string address) : base(address) { } } }