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 ShareItemsWithMoreFun v0.2.2
ShareItemsWithMoreFun.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.CaptainSupplyDrop; using EntityStates.HallowedCauldron; using HG; using On.EntityStates.CaptainSupplyDrop; using On.EntityStates.HallowedCauldron; using On.RoR2; using On.RoR2.Quests.CompulsionQuests; using On.RoR2.UI; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Artifacts; using RoR2.Orbs; using RoR2.Quests; using RoR2.Quests.CompulsionQuests; using RoR2.UI; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.ResourceManagement.ResourceLocations; [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("ShareItemsWithMoreFun")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.2.0")] [assembly: AssemblyInformationalVersion("0.2.2+9cbb2eb87ee97e4840e21e4af04a3bf62c8825ba")] [assembly: AssemblyProduct("ShareItemsWithMoreFun")] [assembly: AssemblyTitle("ShareItemsWithMoreFun")] [assembly: AssemblyVersion("0.2.2.0")] namespace ShareItemsWithMoreFun; internal static class BossRewards { private const BindingFlags Private = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo RngField = typeof(BossGroup).GetField("rng", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo BossDropsField = typeof(BossGroup).GetField("bossDrops", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo BossDropTablesField = typeof(BossGroup).GetField("bossDropTables", BindingFlags.Instance | BindingFlags.NonPublic); public static void Install() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if (RngField == null || BossDropsField == null || BossDropTablesField == null) { Plugin.Log.LogWarning((object)"Récompense du boss : champs de BossGroup introuvables, la récompense reste vanilla."); } else { BossGroup.DropRewards += new hook_DropRewards(BossGroup_DropRewards); } } private static void BossGroup_DropRewards(orig_DropRewards orig, BossGroup self) { Run instance = Run.instance; if (!NetworkServer.active || !Object.op_Implicit((Object)(object)instance) || !ModConfig.Enabled.Value || !ModConfig.InstancedBossRewards.Value || !self.scaleRewardsByPlayerCount || !Object.op_Implicit((Object)(object)self.dropPosition) || !IsTeleporterBoss(self)) { orig.Invoke(self); return; } List<CharacterMaster> list = PlayerResolver.ShareOwners(ModConfig.ReviveDeadPlayersAfterTeleporter.Value); object? value = RngField.GetValue(self); Xoroshiro128Plus val = (Xoroshiro128Plus)((value is Xoroshiro128Plus) ? value : null); if (list.Count == 0 || val == null) { orig.Invoke(self); return; } int dropped = 0; try { DropPerPlayer(self, instance, list, val, ref dropped); } catch (Exception arg) { Plugin.Log.LogError((object)$"Récompense du boss : {arg}"); if (dropped == 0) { orig.Invoke(self); } } } private static bool IsTeleporterBoss(BossGroup boss) { TeleporterInteraction instance = TeleporterInteraction.instance; if (!Object.op_Implicit((Object)(object)instance) || !((Object)(object)instance.bossGroup == (Object)(object)boss)) { return Object.op_Implicit((Object)(object)((Component)boss).GetComponentInParent<TeleporterInteraction>()); } return true; } private static void DropPerPlayer(BossGroup boss, Run run, List<CharacterMaster> players, Xoroshiro128Plus rng, ref int dropped) { //IL_0056: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) List<UniquePickup> list = BossDropsField.GetValue(boss) as List<UniquePickup>; List<PickupDropTable> list2 = BossDropTablesField.GetValue(boss) as List<PickupDropTable>; bool flag = list != null && list.Count > 0; bool flag2 = list2 != null && list2.Count > 0; UniquePickup val = default(UniquePickup); if (Object.op_Implicit((Object)(object)boss.dropTable)) { val = boss.dropTable.GeneratePickup(rng); } else { List<PickupIndex> list3 = (boss.forceTier3Reward ? run.availableTier3DropList : run.availableTier2DropList); ((UniquePickup)(ref val))..ctor(rng.NextElementUniform<PickupIndex>(list3)); } int num = 1 + Math.Max(0, boss.bonusRewardCount); int num2 = num * players.Count; Xoroshiro128Plus rng2 = new Xoroshiro128Plus(rng.nextUlong); Vector3 val2 = Quaternion.AngleAxis((float)Random.Range(0, 360), Vector3.up) * (Vector3.up * 40f + Vector3.forward * 5f); Quaternion val3 = Quaternion.AngleAxis(360f / (float)num2, Vector3.up); Vector3 position = boss.dropPosition.position; foreach (CharacterMaster player in players) { using (DropContext.Begin(player, convertToChoices: true, rng2)) { for (int i = 0; i < num; i++) { UniquePickup val4 = val; if ((flag || flag2) && rng.nextNormalizedFloat <= boss.bossDropChance) { if (flag2) { PickupDropTable val5 = rng.NextElementUniform<PickupDropTable>(list2); if (Object.op_Implicit((Object)(object)val5)) { val4 = val5.GeneratePickup(rng); } } else { val4 = rng.NextElementUniform<UniquePickup>(list); } } PickupDropletController.CreatePickupDroplet(val4, position, val2, false); dropped++; val2 = val3 * val2; } } } Plugin.Debug($"Récompense du boss : {num} orbe(s) pour chacune des {players.Count} part(s), dont {players.FindAll((CharacterMaster p) => !Object.op_Implicit((Object)(object)p)).Count} libre(s)"); } } internal static class ChestBalance { private static readonly HashSet<string> BalanceableNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Chest1", "Chest2", "Chest1StealthedVariant", "CategoryChestDamage", "CategoryChestHealing", "CategoryChestUtility", "CategoryChest2Damage Variant", "CategoryChest2Healing Variant", "CategoryChest2Utility Variant", "EquipmentBarrel" }; private static readonly List<GameObject> spawnedChests = new List<GameObject>(); private static bool collecting; public static void Install() { SceneDirector.onPrePopulateSceneServer += delegate { spawnedChests.Clear(); collecting = true; }; SceneDirector.onSpawnInteractableServer += OnSpawnInteractable; SceneDirector.onPostPopulateSceneServer += OnPostPopulate; } private static void OnSpawnInteractable(SceneDirector director, GameObject spawned, DirectorCard card) { if (collecting && Object.op_Implicit((Object)(object)spawned) && IsBalanceable(((Object)spawned).name)) { spawnedChests.Add(spawned); } } private static bool IsBalanceable(string objectName) { string text = ModConfig.NormalizeName(objectName); if (BalanceableNames.Contains(text)) { return ModConfig.IsManagedChestName(text); } return false; } private static void OnPostPopulate(SceneDirector director) { collecting = false; try { RemoveSurplusChests(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Équilibrage des coffres : {arg}"); } finally { spawnedChests.Clear(); } } public static float KeepFraction(int players, float scaling, float baseCredits, float bonusCredits) { if (players <= 1 || scaling >= 1f) { return 1f; } if (baseCredits <= 0f) { baseCredits = 1f; bonusCredits = 0f; } float num = Mathf.Floor(baseCredits * (0.5f + 0.5f * (float)players)) + bonusCredits; float num2 = baseCredits * (1f + Mathf.Clamp01(scaling) * 0.5f * (float)(players - 1)) + bonusCredits; if (!(num > 0f)) { return 1f; } return Mathf.Clamp01(num2 / num); } private static void RemoveSurplusChests() { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown Run instance = Run.instance; if (!NetworkServer.active || !Object.op_Implicit((Object)(object)instance) || !ModConfig.Enabled.Value || !ModConfig.InstancedChests.Value || DelusionChestController.isDelusionEnable || instance is InfiniteTowerRun) { return; } if (InstanceTracker.GetInstancesList<CacheInteractables>().Count > 0) { Plugin.Debug("Équilibrage ignoré : scène d'épreuve"); return; } int participatingPlayerCount = instance.participatingPlayerCount; StageCredits(out var baseCredits, out var bonusCredits); float num = KeepFraction(participatingPlayerCount, (float)ModConfig.MultiplayerChestScaling.Value / 100f, baseCredits, bonusCredits); if (num >= 1f) { return; } List<GameObject> list = spawnedChests.FindAll((GameObject chest) => Object.op_Implicit((Object)(object)chest)); int num2 = list.Count - Mathf.RoundToInt((float)list.Count * num); if (num2 > 0) { Xoroshiro128Plus val = new Xoroshiro128Plus(instance.stageRng.nextUlong); for (int num3 = 0; num3 < num2; num3++) { int num4 = val.RangeInt(num3, list.Count); List<GameObject> list2 = list; int index = num3; int index2 = num4; GameObject value = list[num4]; GameObject value2 = list[num3]; list2[index] = value; list[index2] = value2; NetworkServer.Destroy(list[num3]); } Plugin.Debug($"Équilibrage : {num2} coffre(s) retiré(s) sur {list.Count} ({participatingPlayerCount} joueurs, réglage {ModConfig.MultiplayerChestScaling.Value} %)"); } } private static void StageCredits(out float baseCredits, out float bonusCredits) { //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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) baseCredits = 0f; bonusCredits = 0f; ClassicStageInfo val = (Object.op_Implicit((Object)(object)SceneInfo.instance) ? ((Component)SceneInfo.instance).GetComponent<ClassicStageInfo>() : null); if (!Object.op_Implicit((Object)(object)val)) { return; } baseCredits = val.sceneDirectorInteractibleCredits; if (val.bonusInteractibleCreditObjects == null) { return; } BonusInteractibleCreditObject[] bonusInteractibleCreditObjects = val.bonusInteractibleCreditObjects; foreach (BonusInteractibleCreditObject val2 in bonusInteractibleCreditObjects) { if (Object.op_Implicit((Object)(object)val2.objectThatGrantsPointsIfEnabled) && val2.objectThatGrantsPointsIfEnabled.activeSelf) { bonusCredits += val2.points; } } } } internal static class ChestHooks { private const float DropDelaySeconds = 0.85f; public static void Install() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown ChestBehavior.Start += new hook_Start(ChestBehavior_Start); OptionChestBehavior.Start += new hook_Start(OptionChestBehavior_Start); PurchaseInteraction.OnInteractionBegin += new hook_OnInteractionBegin(PurchaseInteraction_OnInteractionBegin); PurchaseInteraction.SetAvailable += new hook_SetAvailable(PurchaseInteraction_SetAvailable); PurchaseInteraction.GetInteractability += new hook_GetInteractability(PurchaseInteraction_GetInteractability); PurchaseInteraction.onPurchaseGlobalServer += OnPurchaseGlobalServer; ChestBehavior.Open += new hook_Open(ChestBehavior_Open); ChestBehavior.OpenAndGrantViaOrb += new hook_OpenAndGrantViaOrb(ChestBehavior_OpenAndGrantViaOrb); ChestBehavior.ItemDrop += new hook_ItemDrop(ChestBehavior_ItemDrop); OptionChestBehavior.Open += new hook_Open(OptionChestBehavior_Open); OptionChestBehavior.ItemDrop += new hook_ItemDrop(OptionChestBehavior_ItemDrop); } private static void ChestBehavior_Start(orig_Start orig, ChestBehavior self) { orig.Invoke(self); if (CanManage(((Component)self).gameObject) && !self.isCommandChest) { bool instanced = HexHooks.IsConceptReliquary(((Component)self).gameObject) || ModConfig.InstancedChests.Value; ManagedChest managedChest = Setup(((Component)self).gameObject, instanced); if (Object.op_Implicit((Object)(object)managedChest)) { managedChest.chest = self; managedChest.baseDropCount = Math.Max(1, self.dropCount); managedChest.neverConvert = HexHooks.IsConceptReliquary(((Component)self).gameObject); } } } private static void OptionChestBehavior_Start(orig_Start orig, OptionChestBehavior self) { orig.Invoke(self); if (ModConfig.InstancedChests.Value && CanManage(((Component)self).gameObject)) { ManagedChest managedChest = Setup(((Component)self).gameObject, instanced: true); if (Object.op_Implicit((Object)(object)managedChest)) { managedChest.optionChest = self; } } } private static bool CanManage(GameObject chestObject) { if (NetworkServer.active && ModConfig.Enabled.Value && !DelusionChestController.isDelusionEnable && Object.op_Implicit((Object)(object)Run.instance)) { if (!ModConfig.IsManagedChestName(((Object)chestObject).name)) { if (ModConfig.InstancedHexes.Value) { return HexHooks.IsConceptReliquary(chestObject); } return false; } return true; } return false; } internal static ManagedChest Setup(GameObject chestObject, bool instanced) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown PurchaseInteraction component = chestObject.GetComponent<PurchaseInteraction>(); if (!Object.op_Implicit((Object)(object)component)) { return null; } ManagedChest orAdd = ManagedChest.GetOrAdd(chestObject); orAdd.serverManaged = true; orAdd.instanced = instanced; orAdd.remoteOpAllowed = instanced && ModConfig.RemoteOpCanOpenChests.Value; orAdd.purchase = component; orAdd.rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong); Plugin.Debug($"Coffre géré : {((Object)chestObject).name} (instancié : {instanced})"); if (instanced) { ChestManagedMessage chestManagedMessage = ChestManagedMessage.For(orAdd); if (chestManagedMessage != null) { NetMessageExtensions.Send((INetMessage)(object)chestManagedMessage, (NetworkDestination)1); } } return orAdd; } private static bool TryGetServerInstanced(Component component, out ManagedChest managed) { managed = (NetworkServer.active ? component.GetComponent<ManagedChest>() : null); if (Object.op_Implicit((Object)(object)managed) && managed.serverManaged && managed.instanced) { return !managed.globallyOpened; } return false; } private static void PurchaseInteraction_OnInteractionBegin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor activator) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if (!TryGetServerInstanced((Component)(object)self, out var managed)) { orig.Invoke(self, activator); return; } CharacterMaster val = PlayerResolver.FromInteractor(activator); if (!Object.op_Implicit((Object)(object)val) || managed.HasOpened(((NetworkBehaviour)val).netId)) { return; } if (Object.op_Implicit((Object)(object)managed.shrine)) { ShrineHooks.Purchase(managed, val, self, activator, orig); return; } if (Object.op_Implicit((Object)(object)managed.chest)) { managed.chest.dropCount = managed.baseDropCount; } managed.purchaseInProgress = true; managed.purchaseSucceeded = false; managed.keepShopOpen = false; try { if (managed.isShopTerminal) { using (DropContext.Begin(val, convertToChoices: false, null)) { orig.Invoke(self, activator); } } else { orig.Invoke(self, activator); } } finally { managed.purchaseInProgress = false; } if (!managed.purchaseSucceeded) { return; } if (managed.isShopTerminal) { OnShopTerminalPurchased(managed, val); return; } int num = ((!Object.op_Implicit((Object)(object)managed.chest)) ? 1 : Math.Max(1, managed.chest.dropCount)); if (Object.op_Implicit((Object)(object)managed.chest)) { managed.chest.dropCount = managed.baseDropCount; } managed.MarkOpened(((NetworkBehaviour)val).netId); ChestMarkers.MarkServer(managed); Plugin.Debug($"{((Object)val).name} a ouvert {((Object)self).name} ({num} drop(s))"); NetMessageExtensions.Send((INetMessage)(object)new ChestOpenedMessage(((NetworkBehaviour)self).netId, ((NetworkBehaviour)val).netId, ChestVisual.PlayOpening), (NetworkDestination)1); ((MonoBehaviour)managed).StartCoroutine(DropAfterDelay(managed, val, num)); } private static void OnShopTerminalPurchased(ManagedChest boughtTerminal, CharacterMaster player) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) MultiShopController shop = boughtTerminal.shop; Plugin.Debug(((Object)player).name + " a acheté dans " + (Object.op_Implicit((Object)(object)shop) ? ((Object)shop).name : ((Object)boughtTerminal).name)); ChestMarkers.MarkServer(boughtTerminal); if (!Object.op_Implicit((Object)(object)shop) || boughtTerminal.keepShopOpen) { boughtTerminal.MarkOpened(((NetworkBehaviour)player).netId); NetMessageExtensions.Send((INetMessage)(object)new ChestOpenedMessage(((NetworkBehaviour)boughtTerminal.purchase).netId, ((NetworkBehaviour)player).netId, ChestVisual.PlayOpening), (NetworkDestination)1); return; } Enumerator<GameObject> enumerator = shop.terminalGameObjectsList.GetEnumerator(); try { while (enumerator.MoveNext()) { GameObject current = enumerator.Current; ManagedChest managedChest = (Object.op_Implicit((Object)(object)current) ? current.GetComponent<ManagedChest>() : null); if (Object.op_Implicit((Object)(object)managedChest) && Object.op_Implicit((Object)(object)managedChest.purchase) && !managedChest.HasOpened(((NetworkBehaviour)player).netId)) { managedChest.MarkOpened(((NetworkBehaviour)player).netId); NetMessageExtensions.Send((INetMessage)(object)new ChestOpenedMessage(((NetworkBehaviour)managedChest.purchase).netId, ((NetworkBehaviour)player).netId, ChestVisual.PlayOpening), (NetworkDestination)1); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } private static void OnPurchaseGlobalServer(PayCostContext context, PayCostResults results) { PurchaseInteraction val = context?.purchaseInteraction; ManagedChest managedChest = default(ManagedChest); if (Object.op_Implicit((Object)(object)val) && ((Component)val).TryGetComponent<ManagedChest>(ref managedChest) && managedChest.purchaseInProgress) { managedChest.purchaseSucceeded = true; } } private static IEnumerator DropAfterDelay(ManagedChest managed, CharacterMaster owner, int dropCount) { yield return (object)new WaitForSeconds(0.85f); if (!Object.op_Implicit((Object)(object)managed) || !NetworkServer.active) { yield break; } DropContext dropContext = null; UniquePickup currentPickup; try { if (Object.op_Implicit((Object)(object)managed.chest)) { ChestBehavior chest = managed.chest; currentPickup = chest.currentPickup; if (!((UniquePickup)(ref currentPickup)).isValid) { chest.Roll(); } chest.dropCount = dropCount; managed.allowItemDrop = true; using (dropContext = DropContext.Begin(owner, !managed.neverConvert, managed.rng)) { chest.ItemDrop(); yield break; } } if (Object.op_Implicit((Object)(object)managed.optionChest)) { managed.optionChest.Roll(); managed.allowItemDrop = true; using (dropContext = DropContext.Begin(owner, convertToChoices: false, managed.rng)) { managed.optionChest.ItemDrop(); yield break; } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Échec du drop de {((Object)managed).name} : {arg}"); int num = dropContext?.dropletsCreated ?? 0; DropPlainItemsAfterFailure(managed, owner, Object.op_Implicit((Object)(object)managed.chest) ? (dropCount - num) : (1 - num)); } finally { managed.allowItemDrop = false; if (Object.op_Implicit((Object)(object)managed.chest)) { managed.chest.dropCount = managed.baseDropCount; managed.chest.NetworkisChestOpened = false; currentPickup = managed.chest.currentPickup; if (!((UniquePickup)(ref currentPickup)).isValid) { managed.chest.Roll(); } } } } private static void DropPlainItemsAfterFailure(ManagedChest managed, CharacterMaster owner, int missing) { //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_0078: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (missing <= 0) { return; } try { if (Object.op_Implicit((Object)(object)managed.optionChest)) { managed.allowItemDrop = true; using (DropContext.Begin(owner, convertToChoices: false, null)) { managed.optionChest.ItemDrop(); return; } } ChestBehavior chest = managed.chest; if (!Object.op_Implicit((Object)(object)chest) || !Object.op_Implicit((Object)(object)chest.dropTransform)) { return; } Vector3 val = chest.dropTransform.position + Vector3.up * 1.5f; Vector3 val2 = Vector3.up * chest.dropUpVelocityStrength + chest.dropTransform.forward * chest.dropForwardVelocityStrength; Quaternion val3 = Quaternion.AngleAxis(360f / (float)missing, Vector3.up); using (DropContext.Begin(owner, convertToChoices: false, null)) { for (int i = 0; i < missing; i++) { UniquePickup currentPickup = chest.currentPickup; if (!((UniquePickup)(ref currentPickup)).isValid) { chest.Roll(); } currentPickup = chest.currentPickup; if (!((UniquePickup)(ref currentPickup)).isValid) { break; } PickupDropletController.CreatePickupDroplet(chest.currentPickup, val, val2, false); val2 = val3 * val2; chest.Roll(); } } } catch (Exception arg) { Plugin.Log.LogError((object)$"Le drop de secours a aussi échoué : {arg}"); } } private static void PurchaseInteraction_SetAvailable(orig_SetAvailable orig, PurchaseInteraction self, bool newAvailable) { if (newAvailable || !TryGetServerInstanced((Component)(object)self, out var managed) || !managed.purchaseInProgress) { orig.Invoke(self, newAvailable); } } private static void ChestBehavior_Open(orig_Open orig, ChestBehavior self) { if (TryGetServerInstanced((Component)(object)self, out var managed)) { if (managed.purchaseInProgress) { return; } managed.globallyOpened = true; Plugin.Debug(((Object)self).name + " ouvert hors achat : retour au comportement vanilla"); } orig.Invoke(self); } private static void ChestBehavior_OpenAndGrantViaOrb(orig_OpenAndGrantViaOrb orig, ChestBehavior self, Interactor interactor) { if (TryGetServerInstanced((Component)(object)self, out var managed)) { if (managed.purchaseInProgress) { return; } managed.globallyOpened = true; } orig.Invoke(self, interactor); } private static void OptionChestBehavior_Open(orig_Open orig, OptionChestBehavior self) { if (TryGetServerInstanced((Component)(object)self, out var managed)) { if (managed.purchaseInProgress) { return; } managed.globallyOpened = true; } orig.Invoke(self); } private static void ChestBehavior_ItemDrop(orig_ItemDrop orig, ChestBehavior self) { ManagedChest managedChest = (NetworkServer.active ? ((Component)self).GetComponent<ManagedChest>() : null); if (!Object.op_Implicit((Object)(object)managedChest) || !managedChest.serverManaged || managedChest.globallyOpened) { orig.Invoke(self); return; } if (managedChest.instanced) { if (managedChest.allowItemDrop) { managedChest.allowItemDrop = false; orig.Invoke(self); } return; } using (DropContext.Begin(PlayerResolver.FromInteractor(Object.op_Implicit((Object)(object)managedChest.purchase) ? managedChest.purchase.lastActivator : null), convertToChoices: true, managedChest.rng)) { orig.Invoke(self); } } private static void OptionChestBehavior_ItemDrop(orig_ItemDrop orig, OptionChestBehavior self) { ManagedChest managedChest = (NetworkServer.active ? ((Component)self).GetComponent<ManagedChest>() : null); if (Object.op_Implicit((Object)(object)managedChest) && managedChest.serverManaged && managedChest.instanced && !managedChest.globallyOpened) { if (managedChest.allowItemDrop) { managedChest.allowItemDrop = false; orig.Invoke(self); } } else { orig.Invoke(self); } } private static Interactability PurchaseInteraction_GetInteractability(orig_GetInteractability orig, PurchaseInteraction self, Interactor activator) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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) Interactability val = orig.Invoke(self, activator); ManagedChest component = ((Component)self).GetComponent<ManagedChest>(); if ((int)val == 0 && RemoteOperation.CanOpenChest(self, component, activator)) { val = RemoteOperation.EvaluateAsAllowed(self, activator, orig); } if ((int)val == 0) { return val; } bool alreadyOpened = default(bool); if (Object.op_Implicit((Object)(object)component) && component.IsInstancedFor(activator, out alreadyOpened) && alreadyOpened) { return (Interactability)0; } if (Object.op_Implicit((Object)(object)component) && component.IsShrineCoolingDown(PlayerResolver.FromInteractor(activator))) { return (Interactability)0; } return val; } } internal static class ChestMarkers { private sealed class Marker { public ManagedChest chest; public PingIndicator indicator; } private const float RefreshSeconds = 0.25f; private const BindingFlags Private = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo FixedTimerField = typeof(PingIndicator).GetField("fixedTimer", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly List<Marker> markers = new List<Marker>(); private static GameObject prefab; private static bool buildingMarker; private static float nextRefresh; public static void Install() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown if (FixedTimerField == null) { Plugin.Log.LogWarning((object)"Coffres marqués : minuteur du ping introuvable, le marqueur sera recréé à chaque fin de ping."); } PingerController.CmdPing += new hook_CmdPing(PingerController_CmdPing); Chat.AddMessage_string += new hook_AddMessage_string(Chat_AddMessage_string); } public static void MarkServer(ManagedChest managed) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active && ModConfig.Enabled.Value && ModConfig.PersistentChestMarkers.Value && Object.op_Implicit((Object)(object)managed) && !managed.marked && managed.serverManaged && managed.instanced && !managed.globallyOpened && !Object.op_Implicit((Object)(object)managed.shrine) && Object.op_Implicit((Object)(object)managed.purchase)) { managed.marked = true; Plugin.Debug("Coffre marqué : " + ((Object)managed).name); NetMessageExtensions.Send((INetMessage)(object)new ChestMarkedMessage(((NetworkBehaviour)managed.purchase).netId), (NetworkDestination)1); } } private static void PingerController_CmdPing(orig_CmdPing orig, PingerController self, PingInfo incomingPing) { //IL_0002: 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) orig.Invoke(self, incomingPing); if (NetworkServer.active && incomingPing.active) { GameObject targetGameObject = ((PingInfo)(ref incomingPing)).targetGameObject; ManagedChest managedChest = (Object.op_Implicit((Object)(object)targetGameObject) ? targetGameObject.GetComponent<ManagedChest>() : null); if (Object.op_Implicit((Object)(object)managedChest)) { MarkServer(managedChest); } } } public static void Tick() { if (Time.unscaledTime < nextRefresh) { return; } nextRefresh = Time.unscaledTime + 0.25f; for (int num = markers.Count - 1; num >= 0; num--) { Marker marker = markers[num]; if (!Object.op_Implicit((Object)(object)marker.chest) || !Object.op_Implicit((Object)(object)marker.indicator) || !ShouldShow(marker.chest)) { if (Object.op_Implicit((Object)(object)marker.indicator)) { Object.Destroy((Object)(object)((Component)marker.indicator).gameObject); } markers.RemoveAt(num); } } foreach (ManagedChest instance in ManagedChest.Instances) { if (Object.op_Implicit((Object)(object)instance) && instance.marked && !HasMarker(instance) && ShouldShow(instance)) { Create(instance); } } } private static bool ShouldShow(ManagedChest managed) { if (!managed.marked || !managed.instanced || managed.globallyOpened || Object.op_Implicit((Object)(object)managed.shrine)) { return false; } PurchaseInteraction component = ((Component)managed).GetComponent<PurchaseInteraction>(); if (!Object.op_Implicit((Object)(object)component) || !component.available) { return false; } if (IsCarried(((Component)managed).gameObject)) { return false; } MultiShopController componentInParent = ((Component)managed).GetComponentInParent<MultiShopController>(); if (Object.op_Implicit((Object)(object)componentInParent) && IsCarried(((Component)componentInParent).gameObject)) { return false; } if (LocalUserManager.readOnlyLocalUsersList.Count > 0) { return !managed.OpenedByAllLocalPlayers(); } return false; } private static bool IsCarried(GameObject gameObject) { return Object.op_Implicit((Object)(object)VehicleSeat.FindVehicleSeatWithPassenger(gameObject, (VehicleSeat)null)); } private static bool HasMarker(ManagedChest managed) { foreach (Marker marker in markers) { if ((Object)(object)marker.chest == (Object)(object)managed) { return true; } } return false; } private static void Create(ManagedChest managed) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)prefab)) { prefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/PingIndicator"); if (!Object.op_Implicit((Object)(object)prefab)) { return; } } GameObject val = Object.Instantiate<GameObject>(prefab); PingIndicator component = val.GetComponent<PingIndicator>(); if (!Object.op_Implicit((Object)(object)component)) { Object.Destroy((Object)(object)val); return; } component.pingOwner = null; component.pingOrigin = ((Component)managed).transform.position; component.pingNormal = Vector3.up; component.pingTarget = ((Component)managed).gameObject; buildingMarker = true; try { component.RebuildPing(); } finally { buildingMarker = false; } if (Object.op_Implicit((Object)(object)component.pingText)) { ((Behaviour)component.pingText).enabled = false; } FixedTimerField?.SetValue(component, float.PositiveInfinity); markers.Add(new Marker { chest = managed, indicator = component }); } private static void Chat_AddMessage_string(orig_AddMessage_string orig, string message) { if (!buildingMarker) { orig.Invoke(message); } } } internal static class ChoiceBuilder { private static readonly ItemTag[] SpecialTags; public static bool TryConvert(ref CreatePickupInfo info, Xoroshiro128Plus rng) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) UniquePickup pickup = ((CreatePickupInfo)(ref info)).pickup; PickupDef def = (((UniquePickup)(ref pickup)).isValid ? PickupCatalog.GetPickupDef(pickup.pickupIndex) : null); string text = QualityKey(def); if (text == null || !Object.op_Implicit((Object)(object)Run.instance)) { return false; } if (rng == null) { rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong); } PickupDropTable table = (Object.op_Implicit((Object)(object)info.chest) ? info.chest.dropTable : null); List<PickupIndex> list = CollectCandidates(pickup, text, table, onlyTableLists: true); if (list.Count == 0) { list = CollectCandidates(pickup, text, table, onlyTableLists: false); } int num = Math.Min(ModConfig.ChoiceCount.Value - 1, list.Count); if (num < 1) { return false; } List<UniquePickup> list2 = new List<UniquePickup>(num + 1) { pickup }; for (int i = 0; i < num; i++) { int num2 = rng.RangeInt(i, list.Count); List<PickupIndex> list3 = list; int index = i; List<PickupIndex> list4 = list; int index2 = num2; PickupIndex value = list[num2]; PickupIndex value2 = list[i]; list3[index] = value; list4[index2] = value2; list2.Add(((UniquePickup)(ref pickup)).WithPickupIndex(list[i])); } for (int num3 = list2.Count - 1; num3 > 0; num3--) { int num4 = rng.RangeInt(0, num3 + 1); List<UniquePickup> list5 = list2; int index2 = num3; int index = num4; UniquePickup value3 = list2[num4]; UniquePickup value4 = list2[num3]; list5[index2] = value3; list2[index] = value4; } GameObject val = OptionPickupPrefab.Get(); if (!Object.op_Implicit((Object)(object)val)) { return false; } info.pickerOptions = PickupPickerController.GenerateOptionsFromList<List<UniquePickup>>(list2); info.maxOptionCount = 1; info.prefabOverride = val; ((CreatePickupInfo)(ref info)).pickup = DisplayPickup(pickup, def); Plugin.Debug($"Orbe : {list2.Count} choix de qualité {text}"); return true; } private static string QualityKey(PickupDef def) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_000f: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown if (def == null) { return null; } if ((int)def.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(def.itemIndex); if (!Object.op_Implicit((Object)(object)itemDef) || (int)itemDef.tier == 13) { return null; } if ((int)itemDef.tier != 3) { return "item:" + (int)itemDef.tier; } return "lunar"; } if ((int)def.equipmentIndex != -1) { EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(def.equipmentIndex); if (!Object.op_Implicit((Object)(object)equipmentDef)) { return null; } if (equipmentDef.isLunar) { return "lunar"; } if (!equipmentDef.isBoss) { return "equipment"; } return "equipment:boss"; } return null; } private static List<PickupIndex> CollectCandidates(UniquePickup rolled, string quality, PickupDropTable table, bool onlyTableLists) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) List<PickupIndex> list = new List<PickupIndex>(); HashSet<PickupIndex> hashSet = new HashSet<PickupIndex> { rolled.pickupIndex }; BasicPickupDropTable val = (BasicPickupDropTable)(object)((table is BasicPickupDropTable) ? table : null); bool flag = Object.op_Implicit((Object)(object)val) && val.IsFilterRequired(); foreach (var (list2, num) in DropLists(Run.instance, val)) { if (list2 == null || (onlyTableLists && Object.op_Implicit((Object)(object)val) && num <= 0f)) { continue; } foreach (PickupIndex item in list2) { if (hashSet.Add(item)) { PickupDef pickupDef = PickupCatalog.GetPickupDef(item); if (!(QualityKey(pickupDef) != quality) && (!flag || val.PassesFilter(item)) && AllowsStorageFlags(pickupDef, rolled) && SameSpecialTags(pickupDef, rolled)) { list.Add(item); } } } } return list; } private static IEnumerable<(List<PickupIndex>, float)> DropLists(Run run, BasicPickupDropTable t) { bool b = Object.op_Implicit((Object)(object)t); yield return (run.availableTier1DropList, b ? t.tier1Weight : 1f); yield return (run.availableTier2DropList, b ? t.tier2Weight : 1f); yield return (run.availableTier3DropList, b ? t.tier3Weight : 1f); yield return (run.availableBossDropList, b ? t.bossWeight : 1f); yield return (run.availableLunarItemDropList, b ? t.lunarItemWeight : 1f); yield return (run.availableLunarEquipmentDropList, b ? t.lunarEquipmentWeight : 1f); yield return (run.availableLunarCombinedDropList, b ? t.lunarCombinedWeight : 1f); yield return (run.availableEquipmentDropList, b ? t.equipmentWeight : 1f); yield return (run.availableVoidTier1DropList, b ? t.voidTier1Weight : 1f); yield return (run.availableVoidTier2DropList, b ? t.voidTier2Weight : 1f); yield return (run.availableVoidTier3DropList, b ? t.voidTier3Weight : 1f); yield return (run.availableVoidBossDropList, b ? t.voidBossWeight : 1f); yield return (run.availableFoodTierDropList, b ? t.foodTierWeight : 1f); yield return (run.availablePowerShapeItemsDropList, b ? t.powerShapesWeight : 1f); yield return (run.availableCursedTierDropList, b ? t.cursedWeight : 1f); yield return (run.availableHexTierDropList, b ? t.hexWeight : 1f); yield return (run.availablePageTierDropList, b ? t.pageWeight : 1f); } private static bool SameSpecialTags(PickupDef candidate, UniquePickup rolled) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 //IL_0033: 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_0058: 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) if ((int)candidate.itemIndex == -1) { return true; } PickupDef pickupDef = PickupCatalog.GetPickupDef(rolled.pickupIndex); ItemDef itemDef = ItemCatalog.GetItemDef(candidate.itemIndex); ItemDef val = ((pickupDef != null && (int)pickupDef.itemIndex != -1) ? ItemCatalog.GetItemDef(pickupDef.itemIndex) : null); ItemTag[] specialTags = SpecialTags; foreach (ItemTag val2 in specialTags) { bool num = Object.op_Implicit((Object)(object)itemDef) && itemDef.ContainsTag(val2); bool flag = Object.op_Implicit((Object)(object)val) && val.ContainsTag(val2); if (num != flag) { return false; } } return true; } private static bool AllowsStorageFlags(PickupDef def, UniquePickup rolled) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) if ((int)def.itemIndex == -1) { if (!((UniquePickup)(ref rolled)).isTempItem) { return !rolled.isRental; } return false; } ItemDef itemDef = ItemCatalog.GetItemDef(def.itemIndex); if (((UniquePickup)(ref rolled)).isTempItem && !itemDef.ContainsTag((ItemTag)31)) { return false; } if (rolled.isRental && !itemDef.ContainsTag((ItemTag)40)) { return false; } return true; } private static UniquePickup DisplayPickup(UniquePickup rolled, PickupDef def) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_000a: 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_0019: 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_0026: 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_003e: 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_0038: 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_0052: 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) ItemTier val; if ((int)def.itemIndex != -1) { val = ItemCatalog.GetItemDef(def.itemIndex).tier; } else { if ((int)def.equipmentIndex == -1 || !EquipmentCatalog.GetEquipmentDef(def.equipmentIndex).isLunar) { return rolled; } val = (ItemTier)3; } PickupIndex val2 = PickupCatalog.FindPickupIndex(val); if (!((PickupIndex)(ref val2)).isValid) { return rolled; } return ((UniquePickup)(ref rolled)).WithPickupIndex(val2); } static ChoiceBuilder() { ItemTag[] array = new ItemTag[3]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); SpecialTags = (ItemTag[])(object)array; } } internal static class ClientHooks { public static void Install() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown PurchaseInteraction.ShouldDisplayHologram += new hook_ShouldDisplayHologram(PurchaseInteraction_ShouldDisplayHologram); PurchaseInteraction.ShouldShowOnScanner += new hook_ShouldShowOnScanner(PurchaseInteraction_ShouldShowOnScanner); PurchaseInteraction.ShouldProximityHighlight += new hook_ShouldProximityHighlight(PurchaseInteraction_ShouldProximityHighlight); PickupPickerController.ShouldShowOnScanner += new hook_ShouldShowOnScanner(PickupPickerController_ShouldShowOnScanner); GenericPickupController.ShouldShowOnScanner += new hook_ShouldShowOnScanner(GenericPickupController_ShouldShowOnScanner); MultiShopController.ShouldDisplayHologram += new hook_ShouldDisplayHologram(MultiShopController_ShouldDisplayHologram); } private static bool MultiShopController_ShouldDisplayHologram(orig_ShouldDisplayHologram orig, MultiShopController self, GameObject viewer) { //IL_002c: 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) if (!orig.Invoke(self, viewer)) { return false; } CharacterMaster val = (Object.op_Implicit((Object)(object)viewer) ? PlayerResolver.FromBody(viewer.GetComponent<CharacterBody>()) : null); if (Object.op_Implicit((Object)(object)val) && PlayerResolver.IsLocalPlayer(((NetworkBehaviour)val).netId)) { return !MultiShopHooks.ClosedFor(self, ((NetworkBehaviour)val).netId); } return !MultiShopHooks.ClosedForAllLocalPlayers(self); } private static bool PurchaseInteraction_ShouldDisplayHologram(orig_ShouldDisplayHologram orig, PurchaseInteraction self, GameObject viewer) { if (orig.Invoke(self, viewer) && !OpenedForLocalView(self, viewer)) { return !ShrineCoolingDownForLocalView(self, viewer); } return false; } private static bool ShrineCoolingDownForLocalView(PurchaseInteraction purchase, GameObject viewer) { ManagedChest component = ((Component)purchase).GetComponent<ManagedChest>(); if (Object.op_Implicit((Object)(object)component)) { return component.IsShrineCoolingDown(ShrineHooks.LocalViewer(Object.op_Implicit((Object)(object)viewer) ? viewer.transform : null)); } return false; } private static bool PurchaseInteraction_ShouldShowOnScanner(orig_ShouldShowOnScanner orig, PurchaseInteraction self) { if (orig.Invoke(self)) { return !OpenedForLocalView(self, null); } return false; } private static bool PurchaseInteraction_ShouldProximityHighlight(orig_ShouldProximityHighlight orig, PurchaseInteraction self) { if (orig.Invoke(self)) { return !OpenedForLocalView(self, null); } return false; } private static bool PickupPickerController_ShouldShowOnScanner(orig_ShouldShowOnScanner orig, PickupPickerController self) { if (orig.Invoke(self)) { return !HiddenLocally((Component)(object)self); } return false; } private static bool GenericPickupController_ShouldShowOnScanner(orig_ShouldShowOnScanner orig, GenericPickupController self) { if (orig.Invoke(self)) { return !HiddenLocally((Component)(object)self); } return false; } private static bool HiddenLocally(Component component) { OwnedObject component2 = component.GetComponent<OwnedObject>(); if (Object.op_Implicit((Object)(object)component2)) { return component2.ShouldHideLocally(); } return false; } private static bool OpenedForLocalView(PurchaseInteraction purchase, GameObject viewer) { //IL_0031: 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) ManagedChest component = ((Component)purchase).GetComponent<ManagedChest>(); if (!Object.op_Implicit((Object)(object)component)) { return false; } CharacterMaster val = (Object.op_Implicit((Object)(object)viewer) ? PlayerResolver.FromBody(viewer.GetComponent<CharacterBody>()) : null); if (Object.op_Implicit((Object)(object)val) && PlayerResolver.IsLocalPlayer(((NetworkBehaviour)val).netId)) { if (component.instanced && !component.globallyOpened) { return component.HasOpened(((NetworkBehaviour)val).netId); } return false; } return component.OpenedByAnyLocalPlayer(); } } internal static class ClientVisuals { private sealed class AnimatorBridge : EntityState { public static bool Play(Animator animator, string layer, string state, string playbackRateParam, float duration) { if (!HasState(animator, layer, state)) { return false; } EntityState.PlayAnimationOnAnimator(animator, layer, state, playbackRateParam, duration, 0f); return true; } public static bool Play(Animator animator, string layer, string state) { if (!HasState(animator, layer, state)) { return false; } EntityState.PlayAnimationOnAnimator(animator, layer, state); return true; } private static bool HasState(Animator animator, string layer, string state) { int layerIndex = animator.GetLayerIndex(layer); if (layerIndex >= 0) { return animator.HasState(layerIndex, Animator.StringToHash(state)); } return false; } } private const float OpeningSeconds = 1f; public static void PlayLocalOpening(GameObject chestObject) { ManagedChest component = chestObject.GetComponent<ManagedChest>(); if (Object.op_Implicit((Object)(object)component)) { component.localOpenedShown = true; } if (TryShowShrineDone(chestObject, component)) { return; } ShopTerminalBehavior component2 = chestObject.GetComponent<ShopTerminalBehavior>(); if (Object.op_Implicit((Object)(object)component2)) { if (!Object.op_Implicit((Object)(object)component) || component.OpenedByAllLocalPlayers()) { CloseShopTerminal(component2, playSound: true); } return; } Animator val = FindAnimator(chestObject); if (Object.op_Implicit((Object)(object)val) && AnimatorBridge.Play(val, "Body", "Opening", "Opening.playbackRate", 1f) && Object.op_Implicit((Object)(object)component)) { ((MonoBehaviour)component).StartCoroutine(FinishOpening(val)); } HideReliquaryGlow(chestObject, component); SfxLocator component3 = chestObject.GetComponent<SfxLocator>(); if (Object.op_Implicit((Object)(object)component3) && !string.IsNullOrEmpty(component3.openSound)) { Util.PlaySound(component3.openSound, chestObject); } } public static void ShowOpened(GameObject chestObject) { ManagedChest component = chestObject.GetComponent<ManagedChest>(); if (Object.op_Implicit((Object)(object)component)) { component.localOpenedShown = true; } if (TryShowShrineDone(chestObject, component)) { return; } ShopTerminalBehavior component2 = chestObject.GetComponent<ShopTerminalBehavior>(); if (Object.op_Implicit((Object)(object)component2)) { if (!Object.op_Implicit((Object)(object)component) || component.OpenedByAllLocalPlayers()) { CloseShopTerminal(component2, playSound: false); } return; } Animator val = FindAnimator(chestObject); if (Object.op_Implicit((Object)(object)val)) { AnimatorBridge.Play(val, "Body", "Opened"); } HideReliquaryGlow(chestObject, component); } private static void HideReliquaryGlow(GameObject chestObject, ManagedChest managed) { if (!HexHooks.IsConceptReliquary(chestObject) || (Object.op_Implicit((Object)(object)managed) && !managed.OpenedByAllLocalPlayers())) { return; } PurchaseInteraction component = chestObject.GetComponent<PurchaseInteraction>(); if (component != null) { PurchaseAvailabilityEvent onSetUnavailable = component.onSetUnavailable; if (onSetUnavailable != null) { ((UnityEvent)onSetUnavailable).Invoke(); } } } private static bool TryShowShrineDone(GameObject chestObject, ManagedChest managed) { ShrineChanceBehavior component = chestObject.GetComponent<ShrineChanceBehavior>(); if (!Object.op_Implicit((Object)(object)component)) { return false; } if ((!Object.op_Implicit((Object)(object)managed) || managed.OpenedByAllLocalPlayers()) && Object.op_Implicit((Object)(object)component.symbolTransform)) { ((Component)component.symbolTransform).gameObject.SetActive(false); } return true; } private static void CloseShopTerminal(ShopTerminalBehavior terminal, bool playSound) { GameObject val = (Object.op_Implicit((Object)(object)terminal.pickupDisplay) ? ((Component)terminal.pickupDisplay).gameObject : null); if (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)((Component)terminal).gameObject) { val.SetActive(false); } else { terminal.HideItemDisplay(true); } Animator animator = terminal.animator; if (Object.op_Implicit((Object)(object)animator)) { int layerIndex = animator.GetLayerIndex("Body"); if (layerIndex >= 0 && animator.HasState(layerIndex, Animator.StringToHash("Closing"))) { animator.PlayInFixedTime("Closing", layerIndex); } } if (playSound) { Util.PlaySound("Play_UI_tripleChestShutter", ((Component)terminal).gameObject); } } private static Animator FindAnimator(GameObject chestObject) { ModelLocator component = chestObject.GetComponent<ModelLocator>(); Transform val = (Object.op_Implicit((Object)(object)component) ? component.modelTransform : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } return ((Component)val).GetComponent<Animator>(); } private static IEnumerator FinishOpening(Animator animator) { yield return (object)new WaitForSeconds(1f); if (Object.op_Implicit((Object)(object)animator)) { AnimatorBridge.Play(animator, "Body", "Opened"); } } } internal static class CompatHooks { private sealed class BeaconScope : IDisposable { private readonly bool previousActive; private readonly CharacterMaster previousOwner; private readonly Interactor previousInteractor; public BeaconScope(CharacterMaster owner, Interactor interactor) { previousActive = beaconContextActive; previousOwner = beaconOwner; previousInteractor = beaconInteractor; beaconContextActive = true; beaconOwner = owner; beaconInteractor = interactor; } public void Dispose() { beaconContextActive = previousActive; beaconOwner = previousOwner; beaconInteractor = previousInteractor; } } private static bool beaconContextActive; private static CharacterMaster beaconOwner; private static Interactor beaconInteractor; public static void Install() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown UnlockTargetState.OnEnter += new hook_OnEnter(UnlockTargetState_OnEnter); HackingMainState.FixedUpdate += new hook_FixedUpdate(HackingMainState_FixedUpdate); HackingInProgressState.FixedUpdate += new hook_FixedUpdate(HackingInProgressState_FixedUpdate); HackingMainState.PurchaseInteractionIsValidTarget += new hook_PurchaseInteractionIsValidTarget(PurchaseInteractionIsValidTarget); CompulsionQuestCloakedChest.EnsureCloakedChestExists += new hook_EnsureCloakedChestExists(EnsureCloakedChestExists); } private static bool IsServerInstanced(Component component, out ManagedChest managed) { managed = (Object.op_Implicit((Object)(object)component) ? component.GetComponent<ManagedChest>() : null); if (NetworkServer.active && Object.op_Implicit((Object)(object)managed) && managed.serverManaged && managed.instanced) { return !managed.globallyOpened; } return false; } private static void UnlockTargetState_OnEnter(orig_OnEnter orig, UnlockTargetState self) { PurchaseInteraction target = self.target; int num = (Object.op_Implicit((Object)(object)target) ? target.cost : 0); orig.Invoke(self); if (num > 0 && Object.op_Implicit((Object)(object)target) && target.cost == 0 && IsServerInstanced((Component)(object)target, out var _)) { target.Networkcost = num; } } private static void HackingMainState_FixedUpdate(orig_FixedUpdate orig, HackingMainState self) { using (BeaconContext((EntityState)(object)self)) { orig.Invoke(self); } } private static void HackingInProgressState_FixedUpdate(orig_FixedUpdate orig, HackingInProgressState self) { using (BeaconContext((EntityState)(object)self)) { orig.Invoke(self); } } private static bool PurchaseInteractionIsValidTarget(orig_PurchaseInteractionIsValidTarget orig, PurchaseInteraction purchaseInteraction) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) bool flag = orig.Invoke(purchaseInteraction); if (flag && beaconContextActive && IsServerInstanced((Component)(object)purchaseInteraction, out var managed)) { if (Object.op_Implicit((Object)(object)beaconOwner) && Object.op_Implicit((Object)(object)beaconInteractor) && (int)purchaseInteraction.GetInteractability(beaconInteractor) != 0) { return !IsFreeShrineFor(managed, beaconOwner); } return false; } return flag; } private static bool IsFreeShrineFor(ManagedChest managed, CharacterMaster player) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) return (managed.IsInstancedShrine ? managed.GetShrineState(((NetworkBehaviour)player).netId, create: false) : null)?.free ?? false; } private static IDisposable BeaconContext(EntityState state) { GameObject val = (Object.op_Implicit((Object)(object)state.outer) ? ((Component)state.outer).gameObject : null); GenericOwnership val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<GenericOwnership>() : null); GameObject val3 = (Object.op_Implicit((Object)(object)val2) ? val2.ownerObject : null); CharacterMaster owner = PlayerResolver.FromBody(Object.op_Implicit((Object)(object)val3) ? val3.GetComponent<CharacterBody>() : null); Interactor interactor = (Object.op_Implicit((Object)(object)val3) ? val3.GetComponent<Interactor>() : null); return new BeaconScope(owner, interactor); } private static void EnsureCloakedChestExists(orig_EnsureCloakedChestExists orig, CompulsionQuestCloakedChest self) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) CompulsionQuestTracker val = (Object.op_Implicit((Object)(object)((BaseQuest)self).runner) ? ((Component)((BaseQuest)self).runner).GetComponent<CompulsionQuestTracker>() : null); TeamIndex team = (TeamIndex)((!Object.op_Implicit((Object)(object)val) || (int)val.participatingTeamIndex == -1) ? 1 : ((int)val.participatingTeamIndex)); CharacterMaster questOwner = (Object.op_Implicit((Object)(object)val) ? PlayerResolver.FromBody(val.questOwnerCharacterBody) : null); List<ChestBehavior> list = new List<ChestBehavior>(); foreach (ChestBehavior instances in InstanceTracker.GetInstancesList<ChestBehavior>()) { if (Object.op_Implicit((Object)(object)instances) && ((Object)instances).name.IndexOf("Stealthed", StringComparison.OrdinalIgnoreCase) >= 0 && IsServerInstanced((Component)(object)instances, out var managed) && !AnyPlayerCanStillOpen(managed, team, questOwner)) { list.Add(instances); } } List<ChestBehavior> list2 = new List<ChestBehavior>(); try { foreach (ChestBehavior item in list) { InstanceTracker.Remove<ChestBehavior>(item); list2.Add(item); } orig.Invoke(self); } finally { foreach (ChestBehavior item2 in list2) { if (Object.op_Implicit((Object)(object)item2)) { InstanceTracker.Add<ChestBehavior>(item2); } } } } private static bool AnyPlayerCanStillOpen(ManagedChest managed, TeamIndex team, CharacterMaster questOwner) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)questOwner) && managed.HasOpened(((NetworkBehaviour)questOwner).netId)) { return false; } foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { if (Object.op_Implicit((Object)(object)instance) && instance.isConnected) { CharacterMaster master = instance.master; CharacterBody val = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null); bool flag = Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive; if (Object.op_Implicit((Object)(object)master) && master.teamIndex == team && flag && !managed.HasOpened(((NetworkBehaviour)master).netId)) { return true; } } } return false; } } internal static class Conflicts { private static readonly string[] KnownConflicts = new string[8] { "ThreeChoiceChests", "ItemShare", "ShareSuite", "InstancedLoot", "ArtifactOfPotential", "Artifact of Potential", "Equilibrium", "CatchupLoot" }; public static void WarnAboutKnownConflicts() { List<string> list = new List<string>(); foreach (PluginInfo value2 in Chainloader.PluginInfos.Values) { string text = value2.Metadata.GUID ?? string.Empty; string text2 = value2.Metadata.Name ?? string.Empty; if (text == "com.shareitemswithmorefun") { continue; } string[] knownConflicts = KnownConflicts; foreach (string value in knownConflicts) { if (text2.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { list.Add(text2 + " (" + text + ")"); break; } } } if (list.Count > 0) { Plugin.Log.LogWarning((object)("Mods qui modifient aussi les coffres ou le partage du butin : " + string.Join(", ", list) + ". Butin en double ou comportements étranges possibles : désactivez-les avec ShareItemsWithMoreFun.")); } } } internal static class DifficultyFreeze { private static GameObject freezeObject; public static bool IsFrozen => Object.op_Implicit((Object)(object)freezeObject); public static float FrozenStopwatch { get; private set; } public static int FrozenStageClearCount { get; private set; } public static void FreezeServer() { if (NetworkServer.active && Object.op_Implicit((Object)(object)Run.instance) && !IsFrozen && Apply(Run.instance.GetRunStopwatch(), Run.instance.stageClearCount)) { NetMessageExtensions.Send((INetMessage)(object)new DifficultyFreezeMessage(frozen: true, FrozenStopwatch, FrozenStageClearCount), (NetworkDestination)1); Plugin.Debug($"Téléporteur chargé : difficulté figée à {FrozenStopwatch:0} s"); } } public static void ReleaseServer() { if (NetworkServer.active && IsFrozen) { Release(); NetMessageExtensions.Send((INetMessage)(object)new DifficultyFreezeMessage(frozen: false, 0f, 0), (NetworkDestination)1); Plugin.Debug("Difficulté relâchée"); } } public static bool Apply(float stopwatch, int stageClearCount) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown Release(); if (InstanceTracker.GetInstancesList<OverrideDifficultyArgs>().Count > 0) { return false; } FrozenStopwatch = stopwatch; FrozenStageClearCount = stageClearCount; freezeObject = new GameObject("ShareItemsWithMoreFun_DifficultyFreeze"); freezeObject.SetActive(false); OverrideDifficultyArgs obj = freezeObject.AddComponent<OverrideDifficultyArgs>(); obj.timeOverrideValue = Mathf.Max(0f, stopwatch); obj.stageClearCountOverrideValue = Mathf.Max(0, stageClearCount); freezeObject.SetActive(true); return true; } public static void Release() { if (Object.op_Implicit((Object)(object)freezeObject)) { freezeObject.SetActive(false); Object.Destroy((Object)(object)freezeObject); } freezeObject = null; } } internal class DifficultyFreezeMessage : INetMessage, ISerializableObject { private bool frozen; private float stopwatch; private int stageClearCount; public DifficultyFreezeMessage() { } public DifficultyFreezeMessage(bool frozen, float stopwatch, int stageClearCount) { this.frozen = frozen; this.stopwatch = stopwatch; this.stageClearCount = stageClearCount; } public void Serialize(NetworkWriter writer) { writer.Write(frozen); writer.Write(stopwatch); writer.Write(stageClearCount); } public void Deserialize(NetworkReader reader) { frozen = reader.ReadBoolean(); stopwatch = reader.ReadSingle(); stageClearCount = reader.ReadInt32(); } public void OnReceived() { if (!NetworkServer.active) { if (frozen) { DifficultyFreeze.Apply(stopwatch, stageClearCount); } else { DifficultyFreeze.Release(); } } } } internal sealed class DropContext : IDisposable { public readonly CharacterMaster owner; public readonly bool convertToChoices; public readonly Xoroshiro128Plus rng; public int dropletsCreated; private readonly DropContext previous; private readonly List<GameObject> tagged = new List<GameObject>(); public static DropContext Current { get; private set; } private DropContext(CharacterMaster owner, bool convertToChoices, Xoroshiro128Plus rng, DropContext previous) { this.owner = owner; this.convertToChoices = convertToChoices; this.rng = rng; this.previous = previous; } public static DropContext Begin(CharacterMaster owner, bool convertToChoices, Xoroshiro128Plus rng) { Current = new DropContext(owner, convertToChoices, rng, Current); return Current; } public void Tag(GameObject gameObject) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)owner) && Object.op_Implicit((Object)(object)gameObject)) { OwnedObject.GetOrAdd(gameObject).SetOwnerServer(((NetworkBehaviour)owner).netId, ModConfig.ReserveOrbs.Value, ModConfig.HideOtherPlayersOrbs.Value, ModConfig.RemoteOpCanOpenChests.Value); tagged.Add(gameObject); } } public void Dispose() { Current = previous; foreach (GameObject item in tagged) { if (Object.op_Implicit((Object)(object)item)) { try { OwnerMessage.Broadcast(item); } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } tagged.Clear(); } } internal static class Grant { private static readonly FieldInfo PickupConsumedField = typeof(GenericPickupController).GetField("onPickupConsumed", BindingFlags.Static | BindingFlags.NonPublic); public static bool ToMaster(CharacterMaster master, UniquePickup pickup, Vector3 origin) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: 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_0047: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0078: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) PickupDef pickupDef = PickupCatalog.GetPickupDef(pickup.pickupIndex); CharacterBody val = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null); if (pickupDef == null || pickupDef.attemptGrant == null || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)master.inventory)) { return false; } bool flag = (int)pickupDef.itemIndex != -1; bool flag2 = (int)pickupDef.equipmentIndex != -1; if (!flag && !flag2) { return false; } if (flag2 && val.isRemoteOp) { PendingEquipment.Add(master, pickup); return true; } GrantContext val2 = new GrantContext { body = val, controller = null }; ((GrantContext)(ref val2)).pickup = pickup; val2.position = origin; val2.rotation = Quaternion.identity; GrantContext val3 = val2; pickupDef.attemptGrant.Invoke(ref val3); val.OnPickup((PickupClass)(((UniquePickup)(ref pickup)).isTempItem ? 2 : 3)); if (val3.shouldNotify) { GenericPickupController.SendPickupMessage(master, pickup); } if (val3.shouldDestroy) { RaisePickupConsumed(val, pickup); } if (flag) { DispatchArgs val4 = new DispatchArgs { inventoryToGrantTo = master.inventory, itemIndex = pickupDef.itemIndex, origin = origin, permanentCount = 0, temporaryCount = 0f, rentalCount = 0, travelDuration = 1f, isPickup = false, onArrivalBehavior = delegate { } }; NetworkIdentity networkIdentity = val.networkIdentity; val4.orbDestinationOverride = Either<NetworkIdentity, HurtBox>.op_Implicit(ref networkIdentity); ItemTransferOrb.DispatchItemTransferOrb(val4); } else if (!val3.shouldDestroy) { UniquePickup pickup2 = ((GrantContext)(ref val3)).pickup; if (((UniquePickup)(ref pickup2)).isValid) { UniquePickup pickup3 = ((GrantContext)(ref val3)).pickup; pickup3.ignoreArtifactBasedPickupReplacements = true; using (DropContext.Begin(master, convertToChoices: false, null)) { PickupDropletController.CreatePickupDroplet(pickup3, origin + Vector3.up, Vector3.up * 15f, false); } } } return true; } private static void RaisePickupConsumed(CharacterBody body, UniquePickup pickup) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) try { (PickupConsumedField?.GetValue(null) as Action<CharacterBody, UniquePickup>)?.Invoke(body, pickup); } catch (Exception ex) { Plugin.Log.LogError((object)ex); } } } internal static class HexHooks { private sealed class HexShares { public readonly List<PlayerCharacterMasterController> players = new List<PlayerCharacterMasterController>(); public readonly List<int> given = new List<int>(); } private const string ConceptReliquaryName = "HollowChestFree"; private static readonly ConditionalWeakTable<GrantHexes, HexShares> shares = new ConditionalWeakTable<GrantHexes, HexShares>(); public static void Install() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown GrantHexes.SpawnHex += new hook_SpawnHex(GrantHexes_SpawnHex); } public static bool IsConceptReliquary(GameObject gameObject) { return ModConfig.NormalizeName(((Object)gameObject).name) == "HollowChestFree"; } private static void GrantHexes_SpawnHex(orig_SpawnHex orig, GrantHexes self) { if (!NetworkServer.active || !ModConfig.Enabled.Value || !ModConfig.InstancedHexes.Value) { orig.Invoke(self); return; } HexShares orCreateValue = shares.GetOrCreateValue(self); foreach (PlayerCharacterMasterController instance2 in PlayerCharacterMasterController.instances) { if (Object.op_Implicit((Object)(object)instance2) && Object.op_Implicit((Object)(object)instance2.master) && !orCreateValue.players.Contains(instance2)) { orCreateValue.players.Add(instance2); orCreateValue.given.Add(0); } } int num = -1; for (int i = 0; i < orCreateValue.players.Count; i++) { if (Object.op_Implicit((Object)(object)orCreateValue.players[i]) && (num < 0 || orCreateValue.given[i] < orCreateValue.given[num])) { num = i; } } if (num < 0) { orig.Invoke(self); return; } orCreateValue.given[num]++; TeleporterInteraction instance = TeleporterInteraction.instance; bool reviveComing = ModConfig.ReviveDeadPlayersAfterTeleporter.Value && (!Object.op_Implicit((Object)(object)instance) || !instance.isCharged); CharacterMaster val = PlayerResolver.ShareOwner(orCreateValue.players[num], reviveComing); using (DropContext.Begin(val, convertToChoices: false, null)) { orig.Invoke(self); } Plugin.Debug(string.Format("Autel sacré : maléfice pour {0} ({1} pour ce joueur)", Object.op_Implicit((Object)(object)val) ? ((Object)val).name : "tous", orCreateValue.given[num])); } } internal static class LateJoinSync { public static void Install() { NetworkUser.onNetworkUserLoadedSceneServer += OnNetworkUserLoadedScene; } private static void OnNetworkUserLoadedScene(NetworkUser networkUser) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)networkUser) || ((NetworkBehaviour)networkUser).isLocalPlayer) { return; } NetworkConnection connectionToClient = ((NetworkBehaviour)networkUser).connectionToClient; if (connectionToClient == null || NetworkServer.localConnections.Contains(connectionToClient)) { return; } int num = 0; if (DifficultyFreeze.IsFrozen) { NetMessageExtensions.Send((INetMessage)(object)new DifficultyFreezeMessage(frozen: true, DifficultyFreeze.FrozenStopwatch, DifficultyFreeze.FrozenStageClearCount), connectionToClient); num++; } foreach (ManagedChest item in new List<ManagedChest>(ManagedChest.Instances)) { if (!Object.op_Implicit((Object)(object)item) || !item.serverManaged || !item.instanced || item.globallyOpened || !Object.op_Implicit((Object)(object)item.purchase)) { continue; } ChestManagedMessage chestManagedMessage = ChestManagedMessage.For(item); if (chestManagedMessage != null) { NetMessageExtensions.Send((INetMessage)(object)chestManagedMessage, connectionToClient); num++; } foreach (NetworkInstanceId item2 in item.OpenedBy) { NetMessageExtensions.Send((INetMessage)(object)new ChestOpenedMessage(((NetworkBehaviour)item.purchase).netId, item2, ChestVisual.ShowOpened), connectionToClient); num++; } foreach (KeyValuePair<NetworkInstanceId, ShrinePlayerState> shrineState in item.ShrineStates) { NetMessageExtensions.Send((INetMessage)(object)new ShrineStateMessage(((NetworkBehaviour)item.purchase).netId, shrineState.Key, shrineState.Value, cooldown: false), connectionToClient); num++; } if (item.marked) { NetMessageExtensions.Send((INetMessage)(object)new ChestMarkedMessage(((NetworkBehaviour)item.purchase).netId), connectionToClient); num++; } } foreach (OwnedObject item3 in new List<OwnedObject>(OwnedObject.Instances)) { OwnerMessage ownerMessage = (Object.op_Implicit((Object)(object)item3) ? OwnerMessage.For(((Component)item3).gameObject) : null); if (ownerMessage != null) { NetMessageExtensions.Send((INetMessage)(object)ownerMessage, connectionToClient); num++; } } Plugin.Debug($"État envoyé à {networkUser.userName} ({num} message(s))"); } } internal class ManagedChest : MonoBehaviour { public static readonly HashSet<ManagedChest> Instances = new HashSet<ManagedChest>(); public bool instanced; public bool serverManaged; public bool globallyOpened; public bool remoteOpAllowed; public ChestBehavior chest; public OptionChestBehavior optionChest; public bool isShopTerminal; public MultiShopController shop; public bool keepShopOpen; public PurchaseInteraction purchase; public int baseDropCount = 1; public bool neverConvert; public Xoroshiro128Plus rng; public bool purchaseInProgress; public bool purchaseSucceeded; public bool allowItemDrop; public bool localOpenedShown; public bool marked; public ShrineChanceBehavior shrine; public CharacterMaster shrinePlayer; public bool shrineSucceeded; private readonly HashSet<NetworkInstanceId> openedBy = new HashSet<NetworkInstanceId>(); private readonly Dictionary<NetworkInstanceId, ShrinePlayerState> shrineStates = new Dictionary<NetworkInstanceId, ShrinePlayerState>(); public IEnumerable<NetworkInstanceId> OpenedBy => openedBy; public IEnumerable<KeyValuePair<NetworkInstanceId, ShrinePlayerState>> ShrineStates => shrineStates; public bool IsInstancedShrine { get { if (Object.op_Implicit((Object)(object)shrine) && instanced) { return !globallyOpened; } return false; } } public ShrinePlayerState GetShrineState(NetworkInstanceId masterId, bool create) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!shrineStates.TryGetValue(masterId, out var value) && create) { value = new ShrinePlayerState(); shrineStates[masterId] = value; } return value; } public bool ShrineUsableByAnyLocalPlayer() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) bool flag = false; foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList) { CharacterMaster cachedMaster = readOnlyLocalUsers.cachedMaster; if (Object.op_Implicit((Object)(object)cachedMaster)) { flag = true; if (!openedBy.Contains(((NetworkBehaviour)cachedMaster).netId) && !IsShrineCoolingDown(cachedMaster)) { return true; } } } return !flag; } public bool IsShrineCoolingDown(CharacterMaster player) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (!IsInstancedShrine || !Object.op_Implicit((Object)(object)player)) { return false; } ShrinePlayerState shrineState = GetShrineState(((NetworkBehaviour)player).netId, create: false); if (shrineState != null) { return Time.time < shrineState.readyTime; } return false; } public bool IsInstancedFor(Interactor activator, out bool alreadyOpened) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) alreadyOpened = false; if (!instanced || globallyOpened) { return false; } CharacterMaster val = PlayerResolver.FromInteractor(activator); alreadyOpened = !Object.op_Implicit((Object)(object)val) || openedBy.Contains(((NetworkBehaviour)val).netId); return true; } public bool HasOpened(NetworkInstanceId masterId) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return openedBy.Contains(masterId); } public void MarkOpened(NetworkInstanceId masterId) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) openedBy.Add(masterId); } public bool OpenedByAnyLocalPlayer() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!instanced || globallyOpened) { return false; } foreach (NetworkInstanceId item in openedBy) { if (PlayerResolver.IsLocalPlayer(item)) { return true; } } return false; } public bool OpenedByAllLocalPlayers() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!instanced || globallyOpened || LocalUserManager.readOnlyLocalUsersList.Count == 0) { return false; } foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList) { CharacterMaster cachedMaster = readOnlyLocalUsers.cachedMaster; if (!Object.op_Implicit((Object)(object)cachedMaster) || !openedBy.Contains(((NetworkBehaviour)cachedMaster).netId)) { return false; } } return true; } public static ManagedChest GetOrAdd(GameObject chestObject) { ManagedChest managedChest = chestObject.GetComponent<ManagedChest>(); if (!Object.op_Implicit((Object)(object)managedChest)) { managedChest = chestObject.AddComponent<ManagedChest>(); managedChest.shrine = chestObject.GetComponent<ShrineChanceBehavior>(); } return managedChest; } private void OnEnable() { Instances.Add(this); } private void OnDisable() { Instances.Remove(this); } } internal sealed class ShrinePlayerState { public int attempts; public int successes; public float readyTime; public bool free; } internal enum ChestVisual : byte { None, PlayOpening, ShowOpened } internal class ChestManagedMessage : INetMessage, ISerializableObject { private NetworkInstanceId chestId; private bool remoteOpAllowed; public static ChestManagedMessage For(ManagedChest managed) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)managed) && Object.op_Implicit((Object)(object)managed.purchase)) { NetworkInstanceId netId = ((NetworkBehaviour)managed.purchase).netId; if (!((NetworkInstanceId)(ref netId)).IsEmpty()) { return new ChestManagedMessage { chestId = ((NetworkBehaviour)managed.purchase).netId, remoteOpAllowed = managed.remoteOpAllowed }; } } return null; } public void Serialize(NetworkWriter writer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) writer.Write(chestId); writer.Write(remoteOpAllowed); } public void Deserialize(NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) chestId = reader.ReadNetworkId(); remoteOpAllowed = reader.ReadBoolean(); } public void OnReceived() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { bool allowed = remoteOpAllowed; NetworkLookups.WhenFound(chestId, delegate(GameObject chestObject) { ManagedChest orAdd = ManagedChest.GetOrAdd(chestObject); orAdd.instanced = true; orAdd.remoteOpAllowed = allowed; }); } } } internal class ChestOpenedMessage : INetMessage, ISerializableObject { private NetworkInstanceId chestId; private NetworkInstanceId playerId; private ChestVisual visual; public ChestOpenedMessage() { } public ChestOpenedMessage(NetworkInstanceId chestId, NetworkInstanceId playerId, ChestVisual visual) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) this.chestId = chestId; this.playerId = playerId; this.visual = visual; } public void Serialize(NetworkWriter writer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) writer.Write(chestId); writer.Write(playerId); writer.Write((byte)visual); } public void Deserialize(NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) chestId = reader.ReadNetworkId(); playerId = reader.ReadNetworkId(); visual = (ChestVisual)reader.ReadByte(); } public void OnReceived() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) NetworkInstanceId player = playerId; ChestVisual chestVisual = visual; NetworkLookups.WhenFound(chestId, delegate(GameObject chestObject) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ManagedChest orAdd = ManagedChest.GetOrAdd(chestObject); orAdd.instanced = true; bool flag = !orAdd.HasOpened(player); orAdd.MarkOpened(player); if (PlayerResolver.IsLocalPlayer(player)) { if (chestVisual == ChestVisual.PlayOpening) { ClientVisuals.PlayLocalOpening(chestObject); } else if (chestVisual == ChestVisual.ShowOpened && (flag || !orAdd.localOpenedShown)) { ClientVisuals.ShowOpened(chestObject); } } }); } } internal class ChestMarkedMessage : INetMessage, ISerializableObject { private NetworkInstanceId chestId; public ChestMarkedMessage() { } public ChestMarkedMessage(NetworkInstanceId chestId) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) this.chestId = chestId; } public void Serialize(NetworkWriter writer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) writer.Write(chestId); } public void Deserialize(NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) chestId = reader.ReadNetworkId(); } public void OnReceived() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) NetworkLookups.WhenFound(chestId, delegate(GameObject chestObject) { ManagedChest orAdd = ManagedChest.GetOrAdd(chestObject); orAdd.instanced = true; orAdd.marked = true; }); } } internal class ShrineStateMessage : INetMessage, ISerializableObject { private NetworkInstanceId shrineId; private NetworkInstanceId playerId; private int attempts; private int successes; private bool free; private bool cooldown; public ShrineStateMessage() { } public ShrineStateMessage(NetworkInstanceId shrineId, NetworkInstanceId playerId, ShrinePlayerState state, bool cooldown) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) this.shrineId = shrineId; this.playerId = playerId; attempts = state.attempts; successes = state.successes; free = state.free; this.cooldown = cooldown; } public void Serialize(NetworkWriter writer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) writer.Write(shrineId); writer.Write(playerId); writer.WritePackedUInt32((uint)attempts); writer.WritePackedUInt32((uint)successes); writer.Write(free); writer.Write(cooldown); } public void Deserialize(NetworkReader reader) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) shrineId = reader.ReadNetworkId(); playerId = reader.ReadNetworkId(); attempts = (int)reader.ReadPackedUInt32(); successes = (int)reader.ReadPackedUInt32(); free = reader.ReadBoolean(); cooldown = reader.ReadBoolean(); } public void OnReceived() { //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_004b: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } NetworkInstanceId player = playerId; int playerAttempts = attempts; int playerSuccesses = successes; bool playerFree = free; bool startCooldown = cooldown; NetworkLookups.WhenFound(shrineId, delegate(GameObject shrineObject) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) ManagedChest orAdd = ManagedChest.GetOrAdd(shrineObject); orAdd.instanced = true; ShrinePlayerState shrineState = orAdd.GetShrineState(player, create: true); shrineState.attempts = playerAttempts; shrineState.successes = playerSuccesses; shrineState.free = playerFree; if (startCooldown) { shrineState.readyTime = Time.time