Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DirectorStageFixes v0.1.0
plugins/DirectorStageFixes/DirectorStageFixes.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using On.RoR2; using RoR2; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DirectorStageFixes")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+92bb73866db176ce9103f92b2d6cbe5ab466f85f")] [assembly: AssemblyProduct("DirectorStageFixes")] [assembly: AssemblyTitle("DirectorStageFixes")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DirectorStageFixes { [BepInPlugin("westonkl.DirectorStageFixes", "DirectorStageFixes", "0.1.0")] public class DirectorStageFixesPlugin : BaseUnityPlugin { private enum InteractableType { Printer, Scrapper, EquipmentMultishop, TemporaryItemDispenser, ShrineOfOrder, GunnerTurret, CleansingPool, DroneScrapper } public const string PluginGUID = "westonkl.DirectorStageFixes"; public const string PluginName = "DirectorStageFixes"; public const string PluginVersion = "0.1.0"; private readonly Dictionary<string, ConfigEntry<int>> stageCredits = new Dictionary<string, ConfigEntry<int>>(); private readonly Dictionary<InteractableType, ConfigEntry<int>> spawnLimits = new Dictionary<InteractableType, ConfigEntry<int>>(); private readonly Dictionary<InteractableType, int> spawnCounts = new Dictionary<InteractableType, int>(); private SceneDirector activeDirector; private readonly Dictionary<ShrineChanceBehavior, float> chancePriceMultipliers = new Dictionary<ShrineChanceBehavior, float>(); private PearlPickupDropTable lunarPearlDropTable; private ConfigEntry<float> redPrinterWeightMultiplier; private ConfigEntry<int> tc280CreditCost; private ConfigEntry<int> temporaryItemDistributorGoldCost; private ConfigEntry<int> radarScannerGoldCost; private ConfigEntry<int> legendaryChestGoldCost; private ConfigEntry<float> droneCategoryWeightReduction; private readonly Dictionary<string, ConfigEntry<int>> interactableCosts = new Dictionary<string, ConfigEntry<int>>(); private readonly Dictionary<SpawnCard, SpawnCard> spawnCardOverrides = new Dictionary<SpawnCard, SpawnCard>(); private void Awake() { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Expected O, but got Unknown //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Expected O, but got Unknown //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Expected O, but got Unknown //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Expected O, but got Unknown //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Expected O, but got Unknown //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Expected O, but got Unknown //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Expected O, but got Unknown //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Expected O, but got Unknown //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Expected O, but got Unknown //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Expected O, but got Unknown AddStage("blackbeach", 280); AddStage("blackbeach2", 280); AddStage("golemplains", 280); AddStage("golemplains2", 280); AddStage("snowyforest", 300); AddStage("village", 280); AddStage("villagenight", 310); AddStage("goolake", 280); AddLimit(InteractableType.Printer, "Printers", 4); AddLimit(InteractableType.Scrapper, "Scrappers", 1); AddLimit(InteractableType.EquipmentMultishop, "Equipment Multishops", 2); AddLimit(InteractableType.TemporaryItemDispenser, "Temporary Item Dispensers", 1); AddLimit(InteractableType.ShrineOfOrder, "Shrines of Order", 1); AddLimit(InteractableType.GunnerTurret, "Gunner Turrets", 3); AddLimit(InteractableType.CleansingPool, "Cleansing Pools", 1); AddLimit(InteractableType.DroneScrapper, "Drone Scrappers", 1); redPrinterWeightMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Printer Tweaks", "Red Printer Weight Multiplier", 2f, new ConfigDescription("Multiplier for red printer selection weight. Red printers are blocked until three stages have been completed, then share the total printer cap. Zero disables red printers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); tc280CreditCost = ((BaseUnityPlugin)this).Config.Bind<int>("Drone Tweaks", "TC-280 Director Credit Cost", 20, new ConfigDescription("Director credits spent to spawn a TC-280. This does not change its player purchase price.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10000), Array.Empty<object>())); droneCategoryWeightReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Drone Tweaks", "Drone Category Weight Reduction", 1f, new ConfigDescription("Amount subtracted from each stage's Drones category selection weight, except original weight-14 pools which are set to 10. Clamped at zero; this is a relative weight, not a percentage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); interactableCosts["iscBrokenMegaDrone"] = tc280CreditCost; AddInteractableCost("Legendary Chest", 40, "iscGoldChest"); AddInteractableCost("Halcyon Shrine", 40, "iscShrineHalcyonite", "iscShrineHalcyoniteTier1"); AddInteractableCost("Green Multishop", 30, "iscTripleShopLarge", "iscTrialTripleShopLarge"); AddInteractableCost("Shrine of Order", 5, "iscShrineRestack", "iscShrineRestackSandy", "iscShrineRestackSnowy", "iscShrineRestackQuest"); AddInteractableCost("Shrine of Shaping", 10, "iscShrineColossusAccess"); AddInteractableCost("Void Stalk", 5, "iscVoidCoinBarrel"); temporaryItemDistributorGoldCost = ((BaseUnityPlugin)this).Config.Bind<int>("Purchase Costs", "Temporary Item Distributor Gold Cost", 10, new ConfigDescription("Base gold purchase cost for Temporary Item Distributor terminals.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); radarScannerGoldCost = ((BaseUnityPlugin)this).Config.Bind<int>("Purchase Costs", "Radar Scanner Gold Cost", 30, new ConfigDescription("Base gold purchase cost for Radar Scanners.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); legendaryChestGoldCost = ((BaseUnityPlugin)this).Config.Bind<int>("Purchase Costs", "Legendary Chest Gold Cost", 300, new ConfigDescription("Base gold purchase cost for Legendary Chests, before normal difficulty scaling.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); lunarPearlDropTable = ScriptableObject.CreateInstance<PearlPickupDropTable>(); ((PickupDropTable)lunarPearlDropTable).canDropBeReplaced = false; ShrineChanceBehavior.AddShrineStack += new hook_AddShrineStack(KeepFailedChancePrice); ShrineChanceBehavior.FixedUpdate += new hook_FixedUpdate(RestoreChanceMultiplierAfterRefresh); ShrineRestackBehavior.AddShrineStack += new hook_AddShrineStack(GrantOrderIrradiantPearl); ChestBehavior.Roll += new hook_Roll(SetLunarPodPearlDrop); PurchaseInteraction.Awake += new hook_Awake(SetPurchaseGoldCosts); CampDirector.GenerateInteractableCardSelection += new hook_GenerateInteractableCardSelection(PrepareCampCards); DirectorCardCategorySelection.calcCardWeight += new CalcCardWeight(ReduceShapingWeight); SceneDirector.onGenerateInteractableCardSelection += PrepareInteractableCards; SceneDirector.Start += new hook_Start(ApplyBaseStageCredits); SceneDirector.PopulateScene += new hook_PopulateScene(TrackStagePopulation); SceneDirector.SelectCard += new hook_SelectCard(SelectUncappedCard); SceneDirector.onSpawnInteractableServer += CountInteractable; ((BaseUnityPlugin)this).Logger.LogInfo((object)"DirectorStageFixes loaded."); } private void AddStage(string sceneName, int defaultCredits) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown stageCredits[sceneName] = ((BaseUnityPlugin)this).Config.Bind<int>("Stage Credits", sceneName, defaultCredits, new ConfigDescription("Base solo interactable credit budget for this scene, before multiplayer scaling and conditional bonuses.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); } private void ApplyBaseStageCredits(orig_Start orig, SceneDirector self) { SceneDef currentSceneDef = SceneCatalog.currentSceneDef; ClassicStageInfo val = (Object.op_Implicit((Object)(object)SceneInfo.instance) ? ((Component)SceneInfo.instance).GetComponent<ClassicStageInfo>() : null); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)currentSceneDef) || !stageCredits.TryGetValue(currentSceneDef.cachedName, out var value)) { orig.Invoke(self); return; } int sceneDirectorInteractibleCredits = val.sceneDirectorInteractibleCredits; val.sceneDirectorInteractibleCredits = value.Value; try { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{currentSceneDef.cachedName}: base interactable credits {sceneDirectorInteractibleCredits} -> {value.Value}; native multiplayer scaling and bonuses preserved."); orig.Invoke(self); } finally { if (Object.op_Implicit((Object)(object)val)) { val.sceneDirectorInteractibleCredits = sceneDirectorInteractibleCredits; } } } private void TrackStagePopulation(orig_PopulateScene orig, SceneDirector self) { SceneDef currentSceneDef = SceneCatalog.currentSceneDef; if (!NetworkServer.active) { orig.Invoke(self); return; } if (Object.op_Implicit((Object)(object)currentSceneDef) && stageCredits.ContainsKey(currentSceneDef.cachedName)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{currentSceneDef.cachedName}: scaled interactable credits {self.interactableCredit} before population multipliers."); } ResetChancePriceMultipliers(); activeDirector = self; spawnCounts.Clear(); try { orig.Invoke(self); foreach (KeyValuePair<InteractableType, ConfigEntry<int>> spawnLimit in spawnLimits) { spawnCounts.TryGetValue(spawnLimit.Key, out var value); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{((currentSceneDef != null) ? currentSceneDef.cachedName : null)}: {spawnLimit.Key} spawned {value}/{spawnLimit.Value.Value}"); } } finally { activeDirector = null; spawnCounts.Clear(); } } private void AddLimit(InteractableType type, string name, int defaultLimit) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown spawnLimits[type] = ((BaseUnityPlugin)this).Config.Bind<int>("Spawn Limits", name, defaultLimit, new ConfigDescription("Maximum successful director spawns per stage. Printers share one cap across all rarities. Zero disables this type.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); } private static bool TryGetType(DirectorCard card, out InteractableType type) { type = InteractableType.Printer; SpawnCard val = ((card != null) ? card.GetSpawnCard() : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } switch (((Object)val).name.ToLowerInvariant()) { case "iscduplicatorlarge": case "iscduplicatormilitary": case "iscduplicator": case "iscduplicatorwild": case "iscqualityduplicator": case "iscqualityduplicatorlarge": case "iscqualityduplicatormilitary": case "iscqualityduplicatorwild": type = InteractableType.Printer; return true; case "iscdronescrapper": type = InteractableType.DroneScrapper; return true; case "iscqualityscrapper": case "iscscrapper": type = InteractableType.Scrapper; return true; case "isctripleshopequipment": type = InteractableType.EquipmentMultishop; return true; case "iscshrinecleansesandy": case "iscshrinecleansesnowy": case "iscshrinecleanse": type = InteractableType.CleansingPool; return true; case "iscbrokenturret1": type = InteractableType.GunnerTurret; return true; case "iscshrinerestacksandy": case "iscshrinerestacksnowy": case "iscshrinerestack": type = InteractableType.ShrineOfOrder; return true; case "isctemporaryitemsshop": type = InteractableType.TemporaryItemDispenser; return true; default: return false; } } private void AddInteractableCost(string name, int defaultCost, params string[] spawnCardNames) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown ConfigEntry<int> value = ((BaseUnityPlugin)this).Config.Bind<int>("Interactable Costs", name + " Director Credit Cost", defaultCost, new ConfigDescription("Director credits spent to spawn this object. This does not change its player purchase price.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10000), Array.Empty<object>())); foreach (string key in spawnCardNames) { interactableCosts[key] = value; } } private static bool IsRedPrinter(DirectorCard card) { SpawnCard val = ((card != null) ? card.GetSpawnCard() : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } string text = ((Object)val).name.ToLowerInvariant(); if (!(text == "iscduplicatormilitary")) { return text == "iscqualityduplicatormilitary"; } return true; } private static bool IsYellowPrinter(DirectorCard card) { SpawnCard val = ((card != null) ? card.GetSpawnCard() : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } string text = ((Object)val).name.ToLowerInvariant(); if (!(text == "iscduplicatorwild")) { return text == "iscqualityduplicatorwild"; } return true; } private void PrepareInteractableCards(SceneDirector director, DirectorCardCategorySelection selection) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0508: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance)) { return; } bool flag = Run.instance.stageClearCount < 3; SceneDef currentSceneDef = SceneCatalog.currentSceneDef; string text = ((currentSceneDef != null) ? currentSceneDef.cachedName : null); for (int i = 0; i < selection.categories.Length; i++) { Category val = selection.categories[i]; if (string.Equals(val.name, "Drones", StringComparison.OrdinalIgnoreCase)) { float selectionWeight = val.selectionWeight; val.selectionWeight = (Mathf.Approximately(selectionWeight, 14f) ? 10f : Mathf.Max(0f, selectionWeight - droneCategoryWeightReduction.Value)); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{text}: Drones category weight {selectionWeight} -> {val.selectionWeight}."); } List<DirectorCard> list = new List<DirectorCard>(); bool flag2 = false; DirectorCard[] cards = val.cards; foreach (DirectorCard val2 in cards) { if (val2 == null) { continue; } if (TryGetType(val2, out var type) && type == InteractableType.Printer) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{text}: {((Object)val2.GetSpawnCard()).name} baseline weight={val2.selectionWeight}, category={val.name}, category weight={val.selectionWeight}"); } if (IsYellowPrinter(val2)) { if (!Object.op_Implicit((Object)(object)Run.instance) || Run.instance.stageClearCount < 1) { ((BaseUnityPlugin)this).Logger.LogInfo((object)(text + ": yellow printer excluded until run stage 2.")); continue; } DirectorCard val3 = CopyCard(val2); val3.minimumStageCompletions = Mathf.Max(1, val2.minimumStageCompletions); list.Add(val3); continue; } SpawnCard spawnCard = val2.GetSpawnCard(); if (Object.op_Implicit((Object)(object)spawnCard) && interactableCosts.TryGetValue(((Object)spawnCard).name, out var value)) { if (!spawnCardOverrides.TryGetValue(spawnCard, out var value2)) { value2 = Object.Instantiate<SpawnCard>(spawnCard); ((Object)value2).name = ((Object)spawnCard).name; spawnCardOverrides.Add(spawnCard, value2); } value2.directorCreditCost = value.Value; DirectorCard val4 = CopyCard(val2); val4.spawnCard = value2; if (((Object)spawnCard).name == "iscVoidCoinBarrel") { val4.selectionWeight = 2; } list.Add(val4); if (((Object)spawnCard).name == "iscBrokenMegaDrone") { flag2 = true; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{text}: {((Object)spawnCard).name} director cost {spawnCard.directorCreditCost} -> {val4.cost}."); if (((Object)spawnCard).name == "iscBrokenMegaDrone") { ((BaseUnityPlugin)this).Logger.LogInfo((object)(text + ": TC-280 effective weight=0.5.")); } } else if (!IsRedPrinter(val2)) { list.Add(val2); } else if (flag || redPrinterWeightMultiplier.Value == 0f) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{text}: red printer excluded (completed stages={Run.instance.stageClearCount}, multiplier={redPrinterWeightMultiplier.Value})."); } else { DirectorCard val5 = CopyCard(val2); val5.selectionWeight = Mathf.Max(1, Mathf.RoundToInt((float)val2.selectionWeight * redPrinterWeightMultiplier.Value)); val5.minimumStageCompletions = 3; list.Add(val5); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{text}: red printer weight {val2.selectionWeight} -> {val5.selectionWeight}, eligible from run stage 4."); } } if (flag2) { for (int k = 0; k < list.Count; k++) { DirectorCard val6 = CopyCard(list[k]); SpawnCard spawnCard2 = val6.GetSpawnCard(); val6.selectionWeight = ((Object.op_Implicit((Object)(object)spawnCard2) && ((Object)spawnCard2).name == "iscBrokenMegaDrone") ? 1 : checked(val6.selectionWeight * 2)); list[k] = val6; } } if (list.Exists((DirectorCard card) => TryGetType(card, out var type3) && type3 == InteractableType.ShrineOfOrder)) { for (int num = 0; num < list.Count; num++) { DirectorCard val7 = CopyCard(list[num]); InteractableType type2; bool flag3 = TryGetType(val7, out type2) && type2 == InteractableType.ShrineOfOrder; val7.selectionWeight = (flag3 ? ((!flag2) ? 1 : 2) : checked(val7.selectionWeight * 5)); list[num] = val7; } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{text}: Shrine of Order effective weight=0.2, maximum={spawnLimits[InteractableType.ShrineOfOrder].Value} per stage."); } val.cards = list.ToArray(); selection.categories[i] = val; } } private WeightedSelection<DirectorCard> PrepareCampCards(orig_GenerateInteractableCardSelection orig, CampDirector self) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: 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_0120: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return orig.Invoke(self); } DirectorCardCategorySelection interactableDirectorCards = self.interactableDirectorCards; DirectorCardCategorySelection val = interactableDirectorCards; if (!Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)ClassicStageInfo.instance)) { val = ClassicStageInfo.instance.interactableCategories; } if (!Object.op_Implicit((Object)(object)val)) { return orig.Invoke(self); } DirectorCardCategorySelection val2 = ScriptableObject.CreateInstance<DirectorCardCategorySelection>(); val2.CopyFrom(val); try { Category[] categories = val2.categories; foreach (Category val3 in categories) { for (int j = 0; j < val3.cards.Length; j++) { DirectorCard val4 = val3.cards[j]; SpawnCard val5 = ((val4 != null) ? val4.GetSpawnCard() : null); if (Object.op_Implicit((Object)(object)val5) && !(((Object)val5).name != "iscVoidCoinBarrel")) { if (!spawnCardOverrides.TryGetValue(val5, out var value)) { value = Object.Instantiate<SpawnCard>(val5); ((Object)value).name = ((Object)val5).name; spawnCardOverrides.Add(val5, value); } value.directorCreditCost = interactableCosts["iscVoidCoinBarrel"].Value; DirectorCard val6 = CopyCard(val4); val6.spawnCard = value; val6.selectionWeight = 2; val3.cards[j] = val6; ManualLogSource logger = ((BaseUnityPlugin)this).Logger; object[] array = new object[4]; SceneDef currentSceneDef = SceneCatalog.currentSceneDef; array[0] = ((currentSceneDef != null) ? currentSceneDef.cachedName : null); array[1] = val5.directorCreditCost; array[2] = val6.cost; array[3] = val4.selectionWeight; logger.LogInfo((object)string.Format("{0}: Void Stalk camp cost {1} -> {2}, weight {3} -> 2.", array)); } } } self.interactableDirectorCards = val2; return orig.Invoke(self); } finally { self.interactableDirectorCards = interactableDirectorCards; Object.Destroy((Object)(object)val2); } } private void KeepFailedChancePrice(orig_AddShrineStack orig, ShrineChanceBehavior self, Interactor activator) { if (!NetworkServer.active) { orig.Invoke(self, activator); return; } if (chancePriceMultipliers.TryGetValue(self, out var value)) { self.costMultiplierPerPurchase = value; chancePriceMultipliers.Remove(self); } bool failedAttempt = false; bool receivedResult = false; Action<bool, Interactor> action = delegate(bool failed, Interactor user) { if (!((Object)(object)user != (Object)(object)activator)) { failedAttempt = failed; receivedResult = true; } }; ShrineChanceBehavior.onShrineChancePurchaseGlobal += action; try { orig.Invoke(self, activator); } finally { ShrineChanceBehavior.onShrineChancePurchaseGlobal -= action; } if (receivedResult && failedAttempt) { chancePriceMultipliers[self] = self.costMultiplierPerPurchase; self.costMultiplierPerPurchase = 1f; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Shrine of Chance failed: retry price will remain unchanged."); } } private void RestoreChanceMultiplierAfterRefresh(orig_FixedUpdate orig, ShrineChanceBehavior self) { orig.Invoke(self); if (NetworkServer.active && chancePriceMultipliers.TryGetValue(self, out var value)) { PurchaseInteraction component = ((Component)self).GetComponent<PurchaseInteraction>(); if (Object.op_Implicit((Object)(object)component) && component.available) { self.costMultiplierPerPurchase = value; chancePriceMultipliers.Remove(self); } } } private void ResetChancePriceMultipliers() { foreach (KeyValuePair<ShrineChanceBehavior, float> chancePriceMultiplier in chancePriceMultipliers) { if (Object.op_Implicit((Object)(object)chancePriceMultiplier.Key)) { chancePriceMultiplier.Key.costMultiplierPerPurchase = chancePriceMultiplier.Value; } } chancePriceMultipliers.Clear(); } private void GrantOrderIrradiantPearl(orig_AddShrineStack orig, ShrineRestackBehavior self, Interactor interactor) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, interactor); if (NetworkServer.active && Object.op_Implicit((Object)(object)interactor)) { CharacterBody component = ((Component)interactor).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.master) && Object.op_Implicit((Object)(object)component.master.inventory)) { component.master.inventory.GiveItemPermanent(Items.ShinyPearl.itemIndex, 1); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Shrine of Order shuffled inventory and granted one Irradiant Pearl to its user."); } } } private void SetLunarPodPearlDrop(orig_Roll orig, ChestBehavior self) { if (NetworkServer.active) { PurchaseInteraction component = ((Component)self).GetComponent<PurchaseInteraction>(); if (Object.op_Implicit((Object)(object)component) && component.displayNameToken == "LUNAR_CHEST_NAME") { self.dropTable = (PickupDropTable)(object)lunarPearlDropTable; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Lunar Pod reward set to a regular Pearl."); } } orig.Invoke(self); } private void SetPurchaseGoldCosts(orig_Awake orig, PurchaseInteraction self) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (NetworkServer.active && (int)self.costType == 1) { ConfigEntry<int> val = null; if (self.displayNameToken == "TEMPORARYITEMSSHOP_TERMINAL_NAME") { val = temporaryItemDistributorGoldCost; } else if (self.displayNameToken == "RADIOTOWER_NAME") { val = radarScannerGoldCost; } else if (self.displayNameToken == "GOLDCHEST_NAME") { val = legendaryChestGoldCost; } if (val != null) { int cost = self.cost; self.Networkcost = val.Value; self.solitudeCost = val.Value; ((BaseUnityPlugin)this).Logger.LogInfo((object)$"{self.displayNameToken} base gold cost {cost} -> {self.cost}."); } } orig.Invoke(self); } private void ReduceShapingWeight(DirectorCard card, ref float weight) { SpawnCard val = ((card != null) ? card.GetSpawnCard() : null); if (NetworkServer.active && Object.op_Implicit((Object)(object)val) && !(((Object)val).name != "iscShrineColossusAccess")) { float num = weight; weight *= 0.5f; ManualLogSource logger = ((BaseUnityPlugin)this).Logger; SceneDef currentSceneDef = SceneCatalog.currentSceneDef; logger.LogInfo((object)$"{((currentSceneDef != null) ? currentSceneDef.cachedName : null)}: Shrine of Shaping normalized selection weight {num} -> {weight}."); } } private static DirectorCard CopyCard(DirectorCard card) { //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_001d: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown return new DirectorCard { spawnCard = card.spawnCard, spawnCardReference = card.spawnCardReference, selectionWeight = card.selectionWeight, minimumStageCompletions = card.minimumStageCompletions, spawnDistance = card.spawnDistance, preventOverhead = card.preventOverhead, requiredUnlockable = card.requiredUnlockable, forbiddenUnlockable = card.forbiddenUnlockable, requiredUnlockableDef = card.requiredUnlockableDef, forbiddenUnlockableDef = card.forbiddenUnlockableDef, isExclusivelyElite = card.isExclusivelyElite, eliteDef = card.eliteDef }; } private DirectorCard SelectUncappedCard(orig_SelectCard orig, SceneDirector self, WeightedSelection<DirectorCard> deck, int maxCost) { //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_002f: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)self != (Object)(object)activeDirector) { return orig.Invoke(self, deck, maxCost); } WeightedSelection<DirectorCard> val = new WeightedSelection<DirectorCard>(8); for (int i = 0; i < deck.Count; i++) { ChoiceInfo<DirectorCard> choice = deck.GetChoice(i); if ((IsYellowPrinter(choice.value) && (!Object.op_Implicit((Object)(object)Run.instance) || Run.instance.stageClearCount < 1)) || (IsRedPrinter(choice.value) && (!Object.op_Implicit((Object)(object)Run.instance) || Run.instance.stageClearCount < 3 || redPrinterWeightMultiplier.Value == 0f))) { continue; } if (TryGetType(choice.value, out var type)) { spawnCounts.TryGetValue(type, out var value); if (value >= spawnLimits[type].Value) { continue; } } val.AddChoice(choice); } return orig.Invoke(self, val, maxCost); } private void CountInteractable(SceneDirector director, GameObject spawnedObject, DirectorCard card) { if (!((Object)(object)director != (Object)(object)activeDirector) && Object.op_Implicit((Object)(object)spawnedObject) && TryGetType(card, out var type)) { spawnCounts.TryGetValue(type, out var value); spawnCounts[type] = value + 1; } } private void OnDestroy() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected O, but got Unknown //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown ShrineChanceBehavior.AddShrineStack -= new hook_AddShrineStack(KeepFailedChancePrice); ShrineChanceBehavior.FixedUpdate -= new hook_FixedUpdate(RestoreChanceMultiplierAfterRefresh); ResetChancePriceMultipliers(); ShrineRestackBehavior.AddShrineStack -= new hook_AddShrineStack(GrantOrderIrradiantPearl); ChestBehavior.Roll -= new hook_Roll(SetLunarPodPearlDrop); if (Object.op_Implicit((Object)(object)lunarPearlDropTable)) { Object.Destroy((Object)(object)lunarPearlDropTable); } PurchaseInteraction.Awake -= new hook_Awake(SetPurchaseGoldCosts); CampDirector.GenerateInteractableCardSelection -= new hook_GenerateInteractableCardSelection(PrepareCampCards); DirectorCardCategorySelection.calcCardWeight -= new CalcCardWeight(ReduceShapingWeight); SceneDirector.onGenerateInteractableCardSelection -= PrepareInteractableCards; SceneDirector.Start -= new hook_Start(ApplyBaseStageCredits); SceneDirector.PopulateScene -= new hook_PopulateScene(TrackStagePopulation); SceneDirector.SelectCard -= new hook_SelectCard(SelectUncappedCard); SceneDirector.onSpawnInteractableServer -= CountInteractable; foreach (SpawnCard value in spawnCardOverrides.Values) { Object.Destroy((Object)(object)value); } spawnCardOverrides.Clear(); } } internal sealed class PearlPickupDropTable : PickupDropTable { public override int GetPickupCount() { return 1; } public override UniquePickup GeneratePickupPreReplacement(Xoroshiro128Plus rng) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) return new UniquePickup(PickupCatalog.FindPickupIndex(Items.Pearl.itemIndex)); } public override void GenerateDistinctPickupsPreReplacement(List<UniquePickup> destination, int desiredCount, Xoroshiro128Plus rng) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (desiredCount > 0) { destination.Add(((PickupDropTable)this).GeneratePickupPreReplacement(rng)); } } } }