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 AllMapValuables v4.0.0
AllMapValuables.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace REPOJP.AllMapValuables { [BepInPlugin("REPOJP.AllMapValuables", "AllMapValuables", "4.0.0")] public sealed class AllMapValuablesPlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.AllMapValuables"; public const string PluginName = "AllMapValuables"; public const string PluginVersion = "4.0.0"; internal static AllMapValuablesPlugin Instance; internal static ManualLogSource ModLogger; private Harmony harmony; private ConfigEntry<bool> enableMod; private ConfigEntry<bool> enableVerboseLog; private ConfigEntry<bool> fallbackToVanillaOnError; private ConfigEntry<bool> excludeCurrentMapFromExtraPool; private readonly Dictionary<string, ConfigEntry<int>> levelWeightConfigs = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); private void Awake() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown try { Instance = this; ModLogger = ((BaseUnityPlugin)this).Logger; ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); enableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnableMod", true, "Enable or disable this mod. このMODの有効無効"); enableVerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "EnableVerboseLog", false, "Enable verbose debug logging. 詳細デバッグログ有効"); fallbackToVanillaOnError = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "FallbackToVanillaOnError", true, "Fall back to vanilla valuable generation when an error occurs. エラー時バニラ生成へ自動復帰"); excludeCurrentMapFromExtraPool = ((BaseUnityPlugin)this).Config.Bind<bool>("A General", "ExcludeCurrentMapFromExtraPool", false, "Exclude the current level from the mixed valuable pool. 現在マップ由来の貴重品を混合候補から除外"); harmony = new Harmony("REPOJP.AllMapValuables"); harmony.PatchAll(); WriteInfo("Loaded AllMapValuables v4.0.0"); } catch (Exception ex) { if (((BaseUnityPlugin)this).Logger != null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failure: Awake failed.\n" + ex)); } } } private void OnDestroy() { try { if (harmony != null) { harmony.UnpatchSelf(); } } catch (Exception ex) { WriteError("Failure: OnDestroy failed.\n" + ex); } } internal bool IsEnabled() { return enableMod != null && enableMod.Value; } internal bool IsVerboseLogEnabled() { return enableVerboseLog != null && enableVerboseLog.Value; } internal bool IsFallbackToVanillaOnErrorEnabled() { return fallbackToVanillaOnError != null && fallbackToVanillaOnError.Value; } internal bool IsExcludeCurrentMapFromExtraPoolEnabled() { return excludeCurrentMapFromExtraPool != null && excludeCurrentMapFromExtraPool.Value; } internal void EnsureLevelWeightConfigs() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown if ((Object)(object)RunManager.instance == (Object)null) { return; } List<Level> allowedSourceLevels = GetAllowedSourceLevels(); foreach (Level item in allowedSourceLevels) { string levelName = GetLevelName(item); if (!string.IsNullOrWhiteSpace(levelName) && !levelWeightConfigs.ContainsKey(levelName)) { levelWeightConfigs[levelName] = ((BaseUnityPlugin)this).Config.Bind<int>("B Level Valuable Weights", levelName, 1, new ConfigDescription("Spawn weight for valuables from this level. このマップ由来貴重品の生成重み", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); } } } internal int GetLevelWeight(Level level) { EnsureLevelWeightConfigs(); string levelName = GetLevelName(level); if (string.IsNullOrWhiteSpace(levelName)) { return 1; } if (levelWeightConfigs.TryGetValue(levelName, out var value) && value != null) { return Mathf.Clamp(value.Value, 1, 10); } return 1; } internal List<Level> GetAllowedSourceLevels() { List<Level> list = new List<Level>(); if ((Object)(object)RunManager.instance == (Object)null) { return list; } if (RunManager.instance.levels != null) { foreach (Level level in RunManager.instance.levels) { AddAllowedLevel(list, level); } } AddAllowedLevel(list, RunManager.instance.levelCurrent); return list; } internal void AddAllowedLevel(List<Level> levels, Level level) { if (levels == null || (Object)(object)level == (Object)null || !IsAllowedSourceLevel(level) || (IsExcludeCurrentMapFromExtraPoolEnabled() && (Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent == (Object)(object)level)) { return; } for (int i = 0; i < levels.Count; i++) { if ((Object)(object)levels[i] == (Object)(object)level) { return; } } levels.Add(level); } internal static bool IsAllowedRuntimeLevel() { try { if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)RunManager.instance.levelCurrent == (Object)null) { return false; } if (!SemiFunc.RunIsLevel()) { return false; } if ((Object)(object)LevelGenerator.Instance == (Object)null || (Object)(object)LevelGenerator.Instance.Level == (Object)null) { return false; } return IsAllowedSourceLevel(LevelGenerator.Instance.Level); } catch { return false; } } internal static bool IsAllowedSourceLevel(Level level) { try { if ((Object)(object)level == (Object)null) { return false; } string levelName = GetLevelName(level); if (IsExcludedLevelName(levelName)) { return false; } if (IsShopOrArenaLevel(level)) { return false; } if (level.ValuablePresets == null || level.ValuablePresets.Count == 0) { return false; } return true; } catch { return false; } } internal static string GetLevelName(Level level) { if ((Object)(object)level == (Object)null) { return string.Empty; } return string.IsNullOrWhiteSpace(((Object)level).name) ? string.Empty : ((Object)level).name.Trim(); } internal static bool IsShopOrArenaLevel(Level level) { if ((Object)(object)level == (Object)null) { return false; } if (InvokeSemiFuncLevelBool("IsLevelShop", level) || InvokeSemiFuncLevelBool("IsLevelArena", level)) { return true; } if (IsLevelInRunManagerField(level, "levelShop") || IsLevelInRunManagerField(level, "levelArena")) { return true; } string text = NormalizeLevelName(GetLevelName(level)); return text.IndexOf("Shop", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Arena", StringComparison.OrdinalIgnoreCase) >= 0; } private static bool InvokeSemiFuncLevelBool(string methodName, Level level) { try { MethodInfo methodInfo = AccessTools.Method(typeof(SemiFunc), methodName, new Type[1] { typeof(Level) }, (Type[])null); if (methodInfo == null) { return false; } object obj = methodInfo.Invoke(null, new object[1] { level }); if (obj is bool) { return (bool)obj; } } catch { return false; } return false; } private static bool IsLevelInRunManagerField(Level level, string fieldName) { try { if ((Object)(object)RunManager.instance == (Object)null || (Object)(object)level == (Object)null || string.IsNullOrWhiteSpace(fieldName)) { return false; } FieldInfo fieldInfo = AccessTools.Field(typeof(RunManager), fieldName); if (fieldInfo == null) { return false; } object value = fieldInfo.GetValue(RunManager.instance); if (value == null) { return false; } Level val = (Level)((value is Level) ? value : null); if ((Object)(object)val != (Object)null) { return IsSameLevel(val, level); } if (!(value is IEnumerable enumerable)) { return false; } foreach (object item in enumerable) { Level val2 = (Level)((item is Level) ? item : null); if ((Object)(object)val2 != (Object)null && IsSameLevel(val2, level)) { return true; } } } catch { return false; } return false; } private static bool IsSameLevel(Level left, Level right) { if ((Object)(object)left == (Object)(object)right) { return true; } string levelName = GetLevelName(left); string levelName2 = GetLevelName(right); return !string.IsNullOrWhiteSpace(levelName) && !string.IsNullOrWhiteSpace(levelName2) && string.Equals(levelName, levelName2, StringComparison.OrdinalIgnoreCase); } private static string NormalizeLevelName(string levelName) { if (string.IsNullOrWhiteSpace(levelName)) { return string.Empty; } string text = levelName.Trim(); if (text.StartsWith("Level - ", StringComparison.OrdinalIgnoreCase)) { text = text.Substring("Level - ".Length).Trim(); } return text; } internal static bool IsExcludedLevelName(string levelName) { if (string.IsNullOrWhiteSpace(levelName)) { return true; } string text = NormalizeLevelName(levelName); return string.Equals(text, "Splash Screen", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Main Menu", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Lobby Menu", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Lobby", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "Tutorial", StringComparison.OrdinalIgnoreCase) || text.IndexOf("Shop", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Arena", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Recording", StringComparison.OrdinalIgnoreCase) >= 0; } internal static void WriteInfo(string message) { if (ModLogger != null) { ModLogger.LogInfo((object)message); } } internal static void WriteWarning(string message) { if (ModLogger != null) { ModLogger.LogWarning((object)message); } } internal static void WriteError(string message) { if (ModLogger != null) { ModLogger.LogError((object)message); } } } [HarmonyPatch(typeof(ValuableDirector), "SetupHost")] internal static class ValuableDirectorSetupHostPatch { private sealed class WeightedPrefabRef { public PrefabRef PrefabRef; public string ResourcePath; public int Weight; public string SourceLevelName; } private sealed class WeightedPoolSet { public readonly List<WeightedPrefabRef> TinyWeighted = new List<WeightedPrefabRef>(); public readonly List<WeightedPrefabRef> SmallWeighted = new List<WeightedPrefabRef>(); public readonly List<WeightedPrefabRef> MediumWeighted = new List<WeightedPrefabRef>(); public readonly List<WeightedPrefabRef> BigWeighted = new List<WeightedPrefabRef>(); public readonly List<WeightedPrefabRef> WideWeighted = new List<WeightedPrefabRef>(); public readonly List<WeightedPrefabRef> TallWeighted = new List<WeightedPrefabRef>(); public readonly List<WeightedPrefabRef> VeryTallWeighted = new List<WeightedPrefabRef>(); public readonly Dictionary<string, WeightedPrefabRef> TinyUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<string, WeightedPrefabRef> SmallUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<string, WeightedPrefabRef> MediumUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<string, WeightedPrefabRef> BigUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<string, WeightedPrefabRef> WideUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<string, WeightedPrefabRef> TallUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public readonly Dictionary<string, WeightedPrefabRef> VeryTallUniqueMap = new Dictionary<string, WeightedPrefabRef>(StringComparer.OrdinalIgnoreCase); public List<PrefabRef> TinyUnique = new List<PrefabRef>(); public List<PrefabRef> SmallUnique = new List<PrefabRef>(); public List<PrefabRef> MediumUnique = new List<PrefabRef>(); public List<PrefabRef> BigUnique = new List<PrefabRef>(); public List<PrefabRef> WideUnique = new List<PrefabRef>(); public List<PrefabRef> TallUnique = new List<PrefabRef>(); public List<PrefabRef> VeryTallUnique = new List<PrefabRef>(); public bool IsCompletelyEmpty() { return TinyWeighted.Count == 0 && SmallWeighted.Count == 0 && MediumWeighted.Count == 0 && BigWeighted.Count == 0 && WideWeighted.Count == 0 && TallWeighted.Count == 0 && VeryTallWeighted.Count == 0; } } [CompilerGenerated] private sealed class <CustomSetupHost>d__52 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ValuableDirector director; private bool <setupSuccess>5__1; private WeightedPoolSet <poolSet>5__2; private List<ValuableVolume> <allVolumes>5__3; private List<ValuableVolume> <tinyVolumes>5__4; private List<ValuableVolume> <smallVolumes>5__5; private List<ValuableVolume> <mediumVolumes>5__6; private List<ValuableVolume> <bigVolumes>5__7; private List<ValuableVolume> <wideVolumes>5__8; private List<ValuableVolume> <tallVolumes>5__9; private List<ValuableVolume> <veryTallVolumes>5__10; private int <totalMaxAmount>5__11; private int[] <maxAmounts>5__12; private string[] <paths>5__13; private int[] <chances>5__14; private List<ValuableVolume>[] <volumeLists>5__15; private List<WeightedPrefabRef>[] <weightedPools>5__16; private int[] <volumeIndex>5__17; private int <index>5__18; private int <selectedCategoryIndex>5__19; private ValuableVolume <targetVolume>5__20; private WeightedPrefabRef <selectedValuable>5__21; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CustomSetupHost>d__52(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <poolSet>5__2 = null; <allVolumes>5__3 = null; <tinyVolumes>5__4 = null; <smallVolumes>5__5 = null; <mediumVolumes>5__6 = null; <bigVolumes>5__7 = null; <wideVolumes>5__8 = null; <tallVolumes>5__9 = null; <veryTallVolumes>5__10 = null; <maxAmounts>5__12 = null; <paths>5__13 = null; <chances>5__14 = null; <volumeLists>5__15 = null; <weightedPools>5__16 = null; <volumeIndex>5__17 = null; <targetVolume>5__20 = null; <selectedValuable>5__21 = null; <>1__state = -2; } private bool MoveNext() { //IL_0860: Unknown result type (might be due to invalid IL or missing references) //IL_086a: Expected O, but got Unknown //IL_08c8: Unknown result type (might be due to invalid IL or missing references) //IL_08d2: Expected O, but got Unknown //IL_0924: Unknown result type (might be due to invalid IL or missing references) //IL_092e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <setupSuccess>5__1 = false; PrepareDirectorState(director); CalculateMaxAmounts(director); <poolSet>5__2 = BuildWeightedPoolSet(); if (<poolSet>5__2.IsCompletelyEmpty()) { AllMapValuablesPlugin.WriteWarning("Failure: Valuable pool is empty. No valuables will be spawned by AllMapValuables."); SetAllMaxAmounts(director, 0); } SetFieldValue(TinyValuablesField, director, <poolSet>5__2.TinyUnique); SetFieldValue(SmallValuablesField, director, <poolSet>5__2.SmallUnique); SetFieldValue(MediumValuablesField, director, <poolSet>5__2.MediumUnique); SetFieldValue(BigValuablesField, director, <poolSet>5__2.BigUnique); SetFieldValue(WideValuablesField, director, <poolSet>5__2.WideUnique); SetFieldValue(TallValuablesField, director, <poolSet>5__2.TallUnique); SetFieldValue(VeryTallValuablesField, director, <poolSet>5__2.VeryTallUnique); <allVolumes>5__3 = GetValuableVolumes(); <tinyVolumes>5__4 = GetVolumesByType(<allVolumes>5__3, (Type)0); <smallVolumes>5__5 = GetVolumesByType(<allVolumes>5__3, (Type)1); <mediumVolumes>5__6 = GetVolumesByType(<allVolumes>5__3, (Type)2); <bigVolumes>5__7 = GetVolumesByType(<allVolumes>5__3, (Type)3); <wideVolumes>5__8 = GetVolumesByType(<allVolumes>5__3, (Type)4); <tallVolumes>5__9 = GetVolumesByType(<allVolumes>5__3, (Type)5); <veryTallVolumes>5__10 = GetVolumesByType(<allVolumes>5__3, (Type)6); ShuffleList(<tinyVolumes>5__4); ShuffleList(<smallVolumes>5__5); ShuffleList(<mediumVolumes>5__6); ShuffleList(<bigVolumes>5__7); ShuffleList(<wideVolumes>5__8); ShuffleList(<tallVolumes>5__9); ShuffleList(<veryTallVolumes>5__10); SetFieldValue(TinyVolumesField, director, <tinyVolumes>5__4); SetFieldValue(SmallVolumesField, director, <smallVolumes>5__5); SetFieldValue(MediumVolumesField, director, <mediumVolumes>5__6); SetFieldValue(BigVolumesField, director, <bigVolumes>5__7); SetFieldValue(WideVolumesField, director, <wideVolumes>5__8); SetFieldValue(TallVolumesField, director, <tallVolumes>5__9); SetFieldValue(VeryTallVolumesField, director, <veryTallVolumes>5__10); ApplyValuableDebugMode(director, <allVolumes>5__3, <tinyVolumes>5__4, <smallVolumes>5__5, <mediumVolumes>5__6, <bigVolumes>5__7, <wideVolumes>5__8, <tallVolumes>5__9, <veryTallVolumes>5__10, <poolSet>5__2); <totalMaxAmount>5__11 = Mathf.Max(0, GetFieldValue<int>(TotalMaxAmountField, director)); <maxAmounts>5__12 = new int[7] { Mathf.Max(0, GetFieldValue<int>(TinyMaxAmountField, director)), Mathf.Max(0, GetFieldValue<int>(SmallMaxAmountField, director)), Mathf.Max(0, GetFieldValue<int>(MediumMaxAmountField, director)), Mathf.Max(0, GetFieldValue<int>(BigMaxAmountField, director)), Mathf.Max(0, GetFieldValue<int>(WideMaxAmountField, director)), Mathf.Max(0, GetFieldValue<int>(TallMaxAmountField, director)), Mathf.Max(0, GetFieldValue<int>(VeryTallMaxAmountField, director)) }; <paths>5__13 = new string[7] { GetFieldValue<string>(TinyPathField, director), GetFieldValue<string>(SmallPathField, director), GetFieldValue<string>(MediumPathField, director), GetFieldValue<string>(BigPathField, director), GetFieldValue<string>(WidePathField, director), GetFieldValue<string>(TallPathField, director), GetFieldValue<string>(VeryTallPathField, director) }; <chances>5__14 = new int[7] { Mathf.Max(1, director.tinyChance), Mathf.Max(1, director.smallChance), Mathf.Max(1, director.mediumChance), Mathf.Max(1, director.bigChance), Mathf.Max(1, director.wideChance), Mathf.Max(1, director.tallChance), Mathf.Max(1, director.veryTallChance) }; <volumeLists>5__15 = new List<ValuableVolume>[7] { <tinyVolumes>5__4, <smallVolumes>5__5, <mediumVolumes>5__6, <bigVolumes>5__7, <wideVolumes>5__8, <tallVolumes>5__9, <veryTallVolumes>5__10 }; <weightedPools>5__16 = new List<WeightedPrefabRef>[7] { <poolSet>5__2.TinyWeighted, <poolSet>5__2.SmallWeighted, <poolSet>5__2.MediumWeighted, <poolSet>5__2.BigWeighted, <poolSet>5__2.WideWeighted, <poolSet>5__2.TallWeighted, <poolSet>5__2.VeryTallWeighted }; <volumeIndex>5__17 = new int[7]; if ((Object)(object)AllMapValuablesPlugin.Instance != (Object)null && AllMapValuablesPlugin.Instance.IsVerboseLogEnabled()) { AllMapValuablesPlugin.WriteInfo($"Pool Summary | Tiny:{<poolSet>5__2.TinyWeighted.Count} Small:{<poolSet>5__2.SmallWeighted.Count} Medium:{<poolSet>5__2.MediumWeighted.Count} Big:{<poolSet>5__2.BigWeighted.Count} Wide:{<poolSet>5__2.WideWeighted.Count} Tall:{<poolSet>5__2.TallWeighted.Count} VeryTall:{<poolSet>5__2.VeryTallWeighted.Count}"); } <index>5__18 = 0; goto IL_07f6; case 1: <>1__state = -1; <targetVolume>5__20 = null; <selectedValuable>5__21 = null; goto IL_07e4; case 2: <>1__state = -1; goto IL_087b; case 3: <>1__state = -1; goto IL_08e3; case 4: { <>1__state = -1; break; } IL_08e3: if (IsMultiplayerRoomActive() && GetFieldValue<int>(CosmeticWorldObjectSpawnPlayerReadyField, director) < PhotonNetwork.CurrentRoom.PlayerCount) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 3; return true; } director.VolumesAndSwitchSetup(); break; IL_07f6: if (<index>5__18 < <totalMaxAmount>5__11) { <selectedCategoryIndex>5__19 = SelectCategoryIndex(<maxAmounts>5__12, <volumeIndex>5__17, <volumeLists>5__15, <weightedPools>5__16, <chances>5__14); if (<selectedCategoryIndex>5__19 != -1) { <targetVolume>5__20 = <volumeLists>5__15[<selectedCategoryIndex>5__19][<volumeIndex>5__17[<selectedCategoryIndex>5__19]]; <selectedValuable>5__21 = PickWeightedPrefab(<weightedPools>5__16[<selectedCategoryIndex>5__19]); if (<selectedValuable>5__21 == null || <selectedValuable>5__21.PrefabRef == null) { <volumeIndex>5__17[<selectedCategoryIndex>5__19]++; goto IL_07e4; } InvokeSpawnValuable(director, <selectedValuable>5__21.PrefabRef, <targetVolume>5__20, <paths>5__13[<selectedCategoryIndex>5__19]); <volumeIndex>5__17[<selectedCategoryIndex>5__19]++; <>2__current = null; <>1__state = 1; return true; } } WriteSpawnShortageLog(director, <maxAmounts>5__12, <volumeIndex>5__17); RpcTargetAmount(director, "ValuablesTargetSetRPC", GetFieldValue<int>(ValuableTargetAmountField, director)); IncrementIntField(ValuableSpawnPlayerReadyField, director); goto IL_087b; IL_087b: if (IsMultiplayerRoomActive() && GetFieldValue<int>(ValuableSpawnPlayerReadyField, director) < PhotonNetwork.CurrentRoom.PlayerCount) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; } RunCosmeticWorldObjectSetup(director, <volumeIndex>5__17, <volumeLists>5__15); goto IL_08e3; IL_07e4: <index>5__18++; goto IL_07f6; } if (IsMultiplayerRoomActive() && GetFieldValue<int>(SwitchSetupPlayerReadyField, director) < PhotonNetwork.CurrentRoom.PlayerCount) { <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 4; return true; } SetFieldValue(SetupCompleteField, director, true); <setupSuccess>5__1 = true; if ((Object)(object)AllMapValuablesPlugin.Instance != (Object)null && AllMapValuablesPlugin.Instance.IsVerboseLogEnabled()) { AllMapValuablesPlugin.WriteInfo("AllMapValuables setup completed."); } if (!<setupSuccess>5__1) { return false; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly MethodInfo SpawnValuableMethod = AccessTools.Method(typeof(ValuableDirector), "SpawnValuable", (Type[])null, (Type[])null); private static readonly MethodInfo SpawnCosmeticWorldObjectMethod = AccessTools.Method(typeof(ValuableDirector), "SpawnCosmeticWorldObject", (Type[])null, (Type[])null); private static readonly MethodInfo CosmeticWorldObjectLevelLoopsGetMethod = AccessTools.Method(typeof(ValuableDirector), "CosmeticWorldObjectLevelLoopsGet", (Type[])null, (Type[])null); private static readonly MethodInfo CosmeticWorldObjectLevelLoopsClampedGetMethod = AccessTools.Method(typeof(ValuableDirector), "CosmeticWorldObjectLevelLoopsClampedGet", (Type[])null, (Type[])null); private static readonly FieldInfo ValuableDebugField = AccessTools.Field(typeof(ValuableDirector), "valuableDebug"); private static readonly FieldInfo SetupCompleteField = AccessTools.Field(typeof(ValuableDirector), "setupComplete"); private static readonly FieldInfo ValuableSpawnPlayerReadyListField = AccessTools.Field(typeof(ValuableDirector), "valuableSpawnPlayerReadyList"); private static readonly FieldInfo ValuableSpawnPlayerReadyField = AccessTools.Field(typeof(ValuableDirector), "valuableSpawnPlayerReady"); private static readonly FieldInfo ValuableTargetAmountField = AccessTools.Field(typeof(ValuableDirector), "valuableTargetAmount"); private static readonly FieldInfo SwitchSetupPlayerReadyListField = AccessTools.Field(typeof(ValuableDirector), "switchSetupPlayerReadyList"); private static readonly FieldInfo SwitchSetupPlayerReadyField = AccessTools.Field(typeof(ValuableDirector), "switchSetupPlayerReady"); private static readonly FieldInfo TotalMaxValueField = AccessTools.Field(typeof(ValuableDirector), "totalMaxValue"); private static readonly FieldInfo TotalCurrentValueField = AccessTools.Field(typeof(ValuableDirector), "totalCurrentValue"); private static readonly FieldInfo TotalMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "totalMaxAmount"); private static readonly FieldInfo TinyMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "tinyMaxAmount"); private static readonly FieldInfo SmallMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "smallMaxAmount"); private static readonly FieldInfo MediumMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "mediumMaxAmount"); private static readonly FieldInfo BigMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "bigMaxAmount"); private static readonly FieldInfo WideMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "wideMaxAmount"); private static readonly FieldInfo TallMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "tallMaxAmount"); private static readonly FieldInfo VeryTallMaxAmountField = AccessTools.Field(typeof(ValuableDirector), "veryTallMaxAmount"); private static readonly FieldInfo TinyValuablesField = AccessTools.Field(typeof(ValuableDirector), "tinyValuables"); private static readonly FieldInfo SmallValuablesField = AccessTools.Field(typeof(ValuableDirector), "smallValuables"); private static readonly FieldInfo MediumValuablesField = AccessTools.Field(typeof(ValuableDirector), "mediumValuables"); private static readonly FieldInfo BigValuablesField = AccessTools.Field(typeof(ValuableDirector), "bigValuables"); private static readonly FieldInfo WideValuablesField = AccessTools.Field(typeof(ValuableDirector), "wideValuables"); private static readonly FieldInfo TallValuablesField = AccessTools.Field(typeof(ValuableDirector), "tallValuables"); private static readonly FieldInfo VeryTallValuablesField = AccessTools.Field(typeof(ValuableDirector), "veryTallValuables"); private static readonly FieldInfo TinyVolumesField = AccessTools.Field(typeof(ValuableDirector), "tinyVolumes"); private static readonly FieldInfo SmallVolumesField = AccessTools.Field(typeof(ValuableDirector), "smallVolumes"); private static readonly FieldInfo MediumVolumesField = AccessTools.Field(typeof(ValuableDirector), "mediumVolumes"); private static readonly FieldInfo BigVolumesField = AccessTools.Field(typeof(ValuableDirector), "bigVolumes"); private static readonly FieldInfo WideVolumesField = AccessTools.Field(typeof(ValuableDirector), "wideVolumes"); private static readonly FieldInfo TallVolumesField = AccessTools.Field(typeof(ValuableDirector), "tallVolumes"); private static readonly FieldInfo VeryTallVolumesField = AccessTools.Field(typeof(ValuableDirector), "veryTallVolumes"); private static readonly FieldInfo TinyPathField = AccessTools.Field(typeof(ValuableDirector), "tinyPath"); private static readonly FieldInfo SmallPathField = AccessTools.Field(typeof(ValuableDirector), "smallPath"); private static readonly FieldInfo MediumPathField = AccessTools.Field(typeof(ValuableDirector), "mediumPath"); private static readonly FieldInfo BigPathField = AccessTools.Field(typeof(ValuableDirector), "bigPath"); private static readonly FieldInfo WidePathField = AccessTools.Field(typeof(ValuableDirector), "widePath"); private static readonly FieldInfo TallPathField = AccessTools.Field(typeof(ValuableDirector), "tallPath"); private static readonly FieldInfo VeryTallPathField = AccessTools.Field(typeof(ValuableDirector), "veryTallPath"); private static readonly FieldInfo CosmeticWorldObjectDebugField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectDebug"); private static readonly FieldInfo CosmeticWorldObjectsSpawnCurveField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectsSpawnCurve"); private static readonly FieldInfo CosmeticWorldObjectsLevelLoopField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectsLevelLoop"); private static readonly FieldInfo CosmeticWorldObjectsLevelLoopsMaxField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectsLevelLoopsMax"); private static readonly FieldInfo CosmeticWorldObjectSetupsField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectSetups"); private static readonly FieldInfo CosmeticWorldObjectSpawnPlayerReadyListField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectSpawnPlayerReadyList"); private static readonly FieldInfo CosmeticWorldObjectSpawnPlayerReadyField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectSpawnPlayerReady"); private static readonly FieldInfo CosmeticWorldObjectTargetAmountField = AccessTools.Field(typeof(ValuableDirector), "cosmeticWorldObjectTargetAmount"); private static readonly FieldInfo RunManagerCosmeticWorldObjectBadLuckCountField = AccessTools.Field(typeof(RunManager), "cosmeticWorldObjectBadLuckCount"); private static bool Prefix(ValuableDirector __instance, ref IEnumerator __result) { if ((Object)(object)AllMapValuablesPlugin.Instance == (Object)null || !AllMapValuablesPlugin.Instance.IsEnabled()) { return true; } if ((Object)(object)GameManager.instance != (Object)null && GameManager.instance.gameMode == 1 && !PhotonNetwork.IsMasterClient) { return true; } if (!AllMapValuablesPlugin.IsAllowedRuntimeLevel()) { return true; } if (!HasRequiredMembers()) { AllMapValuablesPlugin.WriteWarning("Failure: Required ValuableDirector members were not found. Falling back to vanilla generation."); return true; } try { AllMapValuablesPlugin.Instance.EnsureLevelWeightConfigs(); __result = CustomSetupHost(__instance); return false; } catch (Exception ex) { AllMapValuablesPlugin.WriteError("Failure: Failed to start custom valuable generation.\n" + ex); return AllMapValuablesPlugin.Instance.IsFallbackToVanillaOnErrorEnabled(); } } [IteratorStateMachine(typeof(<CustomSetupHost>d__52))] private static IEnumerator CustomSetupHost(ValuableDirector director) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CustomSetupHost>d__52(0) { director = director }; } private static bool HasRequiredMembers() { return SpawnValuableMethod != null && ValuableTargetAmountField != null && ValuableSpawnPlayerReadyField != null && SwitchSetupPlayerReadyField != null && TotalMaxAmountField != null && TinyValuablesField != null && SmallValuablesField != null && MediumValuablesField != null && BigValuablesField != null && WideValuablesField != null && TallValuablesField != null && VeryTallValuablesField != null; } private static void PrepareDirectorState(ValuableDirector director) { SetFieldValue(SetupCompleteField, director, false); SetFieldValue(ValuableTargetAmountField, director, 0); SetFieldValue(TotalCurrentValueField, director, 0f); SetFieldValue(ValuableSpawnPlayerReadyField, director, 0); SetFieldValue(SwitchSetupPlayerReadyField, director, 0); SetFieldValue(ValuableSpawnPlayerReadyListField, director, new List<Player>()); SetFieldValue(SwitchSetupPlayerReadyListField, director, new List<Player>()); SetFieldValue(CosmeticWorldObjectTargetAmountField, director, 0); SetFieldValue(CosmeticWorldObjectSpawnPlayerReadyField, director, 0); SetFieldValue(CosmeticWorldObjectSpawnPlayerReadyListField, director, new List<Player>()); } private static void CalculateMaxAmounts(ValuableDirector director) { if (SemiFunc.RunGetDifficultyMultiplier2() > 0f && !SemiFunc.RunIsArena()) { float num = SemiFunc.RunGetDifficultyMultiplier2(); SetFieldValue(TotalMaxValueField, director, (float)Mathf.RoundToInt(director.totalMaxValueCurve2.Evaluate(num))); SetFieldValue(TinyMaxAmountField, director, Mathf.RoundToInt(director.tinyMaxAmountCurve2.Evaluate(num))); SetFieldValue(SmallMaxAmountField, director, Mathf.RoundToInt(director.smallMaxAmountCurve2.Evaluate(num))); SetFieldValue(MediumMaxAmountField, director, Mathf.RoundToInt(director.mediumMaxAmountCurve2.Evaluate(num))); SetFieldValue(BigMaxAmountField, director, Mathf.RoundToInt(director.bigMaxAmountCurve2.Evaluate(num))); SetFieldValue(WideMaxAmountField, director, Mathf.RoundToInt(director.wideMaxAmountCurve2.Evaluate(num))); SetFieldValue(TallMaxAmountField, director, Mathf.RoundToInt(director.tallMaxAmountCurve2.Evaluate(num))); SetFieldValue(VeryTallMaxAmountField, director, Mathf.RoundToInt(director.veryTallMaxAmountCurve2.Evaluate(num))); } else { float num2 = SemiFunc.RunGetDifficultyMultiplier1(); SetFieldValue(TotalMaxValueField, director, (float)Mathf.RoundToInt(director.totalMaxValueCurve1.Evaluate(num2))); SetFieldValue(TinyMaxAmountField, director, Mathf.RoundToInt(director.tinyMaxAmountCurve1.Evaluate(num2))); SetFieldValue(SmallMaxAmountField, director, Mathf.RoundToInt(director.smallMaxAmountCurve1.Evaluate(num2))); SetFieldValue(MediumMaxAmountField, director, Mathf.RoundToInt(director.mediumMaxAmountCurve1.Evaluate(num2))); SetFieldValue(BigMaxAmountField, director, Mathf.RoundToInt(director.bigMaxAmountCurve1.Evaluate(num2))); SetFieldValue(WideMaxAmountField, director, Mathf.RoundToInt(director.wideMaxAmountCurve1.Evaluate(num2))); SetFieldValue(TallMaxAmountField, director, Mathf.RoundToInt(director.tallMaxAmountCurve1.Evaluate(num2))); SetFieldValue(VeryTallMaxAmountField, director, Mathf.RoundToInt(director.veryTallMaxAmountCurve1.Evaluate(num2))); } } private static void SetAllMaxAmounts(ValuableDirector director, int value) { SetFieldValue(TotalMaxAmountField, director, value); SetFieldValue(TinyMaxAmountField, director, value); SetFieldValue(SmallMaxAmountField, director, value); SetFieldValue(MediumMaxAmountField, director, value); SetFieldValue(BigMaxAmountField, director, value); SetFieldValue(WideMaxAmountField, director, value); SetFieldValue(TallMaxAmountField, director, value); SetFieldValue(VeryTallMaxAmountField, director, value); } private static WeightedPoolSet BuildWeightedPoolSet() { WeightedPoolSet weightedPoolSet = new WeightedPoolSet(); if ((Object)(object)AllMapValuablesPlugin.Instance == (Object)null) { return weightedPoolSet; } List<Level> allowedSourceLevels = AllMapValuablesPlugin.Instance.GetAllowedSourceLevels(); foreach (Level item in allowedSourceLevels) { if ((Object)(object)item == (Object)null || item.ValuablePresets == null || item.ValuablePresets.Count == 0) { continue; } string levelName = AllMapValuablesPlugin.GetLevelName(item); int levelWeight = AllMapValuablesPlugin.Instance.GetLevelWeight(item); foreach (LevelValuables valuablePreset in item.ValuablePresets) { if (!((Object)(object)valuablePreset == (Object)null)) { AddWeightedPrefabs(weightedPoolSet.TinyWeighted, weightedPoolSet.TinyUniqueMap, valuablePreset.tiny, levelWeight, levelName); AddWeightedPrefabs(weightedPoolSet.SmallWeighted, weightedPoolSet.SmallUniqueMap, valuablePreset.small, levelWeight, levelName); AddWeightedPrefabs(weightedPoolSet.MediumWeighted, weightedPoolSet.MediumUniqueMap, valuablePreset.medium, levelWeight, levelName); AddWeightedPrefabs(weightedPoolSet.BigWeighted, weightedPoolSet.BigUniqueMap, valuablePreset.big, levelWeight, levelName); AddWeightedPrefabs(weightedPoolSet.WideWeighted, weightedPoolSet.WideUniqueMap, valuablePreset.wide, levelWeight, levelName); AddWeightedPrefabs(weightedPoolSet.TallWeighted, weightedPoolSet.TallUniqueMap, valuablePreset.tall, levelWeight, levelName); AddWeightedPrefabs(weightedPoolSet.VeryTallWeighted, weightedPoolSet.VeryTallUniqueMap, valuablePreset.veryTall, levelWeight, levelName); } } } weightedPoolSet.TinyUnique = GetUniquePrefabList(weightedPoolSet.TinyUniqueMap); weightedPoolSet.SmallUnique = GetUniquePrefabList(weightedPoolSet.SmallUniqueMap); weightedPoolSet.MediumUnique = GetUniquePrefabList(weightedPoolSet.MediumUniqueMap); weightedPoolSet.BigUnique = GetUniquePrefabList(weightedPoolSet.BigUniqueMap); weightedPoolSet.WideUnique = GetUniquePrefabList(weightedPoolSet.WideUniqueMap); weightedPoolSet.TallUnique = GetUniquePrefabList(weightedPoolSet.TallUniqueMap); weightedPoolSet.VeryTallUnique = GetUniquePrefabList(weightedPoolSet.VeryTallUniqueMap); return weightedPoolSet; } private static void AddWeightedPrefabs(List<WeightedPrefabRef> weightedList, Dictionary<string, WeightedPrefabRef> uniqueMap, List<PrefabRef> source, int levelWeight, string levelName) { if (weightedList == null || uniqueMap == null || source == null || source.Count == 0) { return; } foreach (PrefabRef item in source) { if (item == null || !item.IsValid()) { continue; } string resourcePath = item.ResourcePath; if (!string.IsNullOrWhiteSpace(resourcePath)) { if (uniqueMap.TryGetValue(resourcePath, out var value)) { value.Weight += Mathf.Clamp(levelWeight, 1, 10); continue; } value = new WeightedPrefabRef(); value.PrefabRef = item; value.ResourcePath = resourcePath; value.Weight = Mathf.Clamp(levelWeight, 1, 10); value.SourceLevelName = levelName; uniqueMap.Add(resourcePath, value); weightedList.Add(value); } } } private static List<PrefabRef> GetUniquePrefabList(Dictionary<string, WeightedPrefabRef> uniqueMap) { List<PrefabRef> list = new List<PrefabRef>(); if (uniqueMap == null) { return list; } foreach (KeyValuePair<string, WeightedPrefabRef> item in uniqueMap) { if (item.Value != null && item.Value.PrefabRef != null) { list.Add(item.Value.PrefabRef); } } return list; } private static List<ValuableVolume> GetValuableVolumes() { ValuableVolume[] array = Object.FindObjectsOfType<ValuableVolume>(false); if (array == null || array.Length == 0) { return new List<ValuableVolume>(); } return new List<ValuableVolume>(array); } private static List<ValuableVolume> GetVolumesByType(List<ValuableVolume> allVolumes, Type volumeType) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) List<ValuableVolume> list = new List<ValuableVolume>(); if (allVolumes == null) { return list; } foreach (ValuableVolume allVolume in allVolumes) { if ((Object)(object)allVolume != (Object)null && allVolume.VolumeType == volumeType) { list.Add(allVolume); } } return list; } private static void ShuffleList<T>(List<T> list) { if (list != null && list.Count > 1) { for (int num = list.Count - 1; num > 0; num--) { int index = Random.Range(0, num + 1); T value = list[num]; list[num] = list[index]; list[index] = value; } } } private static void ApplyValuableDebugMode(ValuableDirector director, List<ValuableVolume> allVolumes, List<ValuableVolume> tinyVolumes, List<ValuableVolume> smallVolumes, List<ValuableVolume> mediumVolumes, List<ValuableVolume> bigVolumes, List<ValuableVolume> wideVolumes, List<ValuableVolume> tallVolumes, List<ValuableVolume> veryTallVolumes, WeightedPoolSet poolSet) { string fieldValueAsString = GetFieldValueAsString(ValuableDebugField, director); if (string.Equals(fieldValueAsString, "All", StringComparison.OrdinalIgnoreCase)) { SetFieldValue(TotalMaxAmountField, director, allVolumes.Count); SetFieldValue(TotalMaxValueField, director, 99999f); SetFieldValue(TinyMaxAmountField, director, tinyVolumes.Count); SetFieldValue(SmallMaxAmountField, director, smallVolumes.Count); SetFieldValue(MediumMaxAmountField, director, mediumVolumes.Count); SetFieldValue(BigMaxAmountField, director, bigVolumes.Count); SetFieldValue(WideMaxAmountField, director, wideVolumes.Count); SetFieldValue(TallMaxAmountField, director, tallVolumes.Count); SetFieldValue(VeryTallMaxAmountField, director, veryTallVolumes.Count); } if (string.Equals(fieldValueAsString, "None", StringComparison.OrdinalIgnoreCase) || poolSet == null || poolSet.IsCompletelyEmpty()) { SetAllMaxAmounts(director, 0); } } private static int SelectCategoryIndex(int[] maxAmounts, int[] volumeIndex, List<ValuableVolume>[] volumeLists, List<WeightedPrefabRef>[] weightedPools, int[] chances) { float num = -1f; int result = -1; for (int i = 0; i < volumeLists.Length; i++) { if (volumeIndex[i] < maxAmounts[i] && volumeLists[i] != null && volumeIndex[i] < volumeLists[i].Count && weightedPools[i] != null && weightedPools[i].Count != 0) { int num2 = Random.Range(0, Mathf.Max(1, chances[i])); if ((float)num2 > num) { num = num2; result = i; } } } return result; } private static WeightedPrefabRef PickWeightedPrefab(List<WeightedPrefabRef> weightedPool) { if (weightedPool == null || weightedPool.Count == 0) { return null; } int num = 0; foreach (WeightedPrefabRef item in weightedPool) { if (item != null && item.PrefabRef != null && item.Weight > 0) { num += item.Weight; } } if (num <= 0) { return null; } int num2 = Random.Range(0, num); int num3 = 0; foreach (WeightedPrefabRef item2 in weightedPool) { if (item2 != null && item2.PrefabRef != null && item2.Weight > 0) { num3 += item2.Weight; if (num2 < num3) { return item2; } } } return weightedPool[weightedPool.Count - 1]; } private static void InvokeSpawnValuable(ValuableDirector director, PrefabRef prefabRef, ValuableVolume volume, string path) { SpawnValuableMethod.Invoke(director, new object[3] { prefabRef, volume, path }); } private static void WriteSpawnShortageLog(ValuableDirector director, int[] maxAmounts, int[] volumeIndex) { if ((Object)(object)AllMapValuablesPlugin.Instance == (Object)null || !AllMapValuablesPlugin.Instance.IsVerboseLogEnabled()) { return; } int fieldValue = GetFieldValue<int>(ValuableTargetAmountField, director); int fieldValue2 = GetFieldValue<int>(TotalMaxAmountField, director); if (fieldValue >= fieldValue2) { return; } string[] array = new string[7] { "Tiny", "Small", "Medium", "Big", "Wide", "Tall", "Very Tall" }; for (int i = 0; i < array.Length; i++) { if (volumeIndex[i] < maxAmounts[i]) { AllMapValuablesPlugin.WriteWarning("Could not spawn enough " + array[i] + " valuables."); } } } private static void RpcTargetAmount(ValuableDirector director, string rpcName, int targetAmount) { if (IsMultiplayerRoomActive()) { PhotonView component = ((Component)director).GetComponent<PhotonView>(); if (!((Object)(object)component == (Object)null)) { component.RPC(rpcName, (RpcTarget)0, new object[1] { targetAmount }); } } } private static void RunCosmeticWorldObjectSetup(ValuableDirector director, int[] volumeIndex, List<ValuableVolume>[] volumeLists) { if (CosmeticWorldObjectTargetAmountField == null || CosmeticWorldObjectSpawnPlayerReadyField == null) { return; } SetFieldValue(CosmeticWorldObjectTargetAmountField, director, 0); try { if (SpawnCosmeticWorldObjectMethod == null || CosmeticWorldObjectDebugField == null) { SetCosmeticWorldObjectTargetZero(director); return; } string fieldValueAsString = GetFieldValueAsString(CosmeticWorldObjectDebugField, director); if (string.Equals(fieldValueAsString, "Normal", StringComparison.OrdinalIgnoreCase) && SemiFunc.RunIsLevel()) { RunNormalCosmeticWorldObjectSetup(director, volumeIndex, volumeLists); } else if (string.Equals(fieldValueAsString, "All", StringComparison.OrdinalIgnoreCase)) { InvokeSpawnCosmeticWorldObjectByName(director, "Common", volumeIndex, volumeLists); InvokeSpawnCosmeticWorldObjectByName(director, "Uncommon", volumeIndex, volumeLists); InvokeSpawnCosmeticWorldObjectByName(director, "Rare", volumeIndex, volumeLists); InvokeSpawnCosmeticWorldObjectByName(director, "UltraRare", volumeIndex, volumeLists); } RpcTargetAmount(director, "CosmeticWorldObjectTargetSetRPC", GetFieldValue<int>(CosmeticWorldObjectTargetAmountField, director)); IncrementIntField(CosmeticWorldObjectSpawnPlayerReadyField, director); } catch (Exception ex) { AllMapValuablesPlugin.WriteWarning("Failure: Cosmetic world object reflection setup failed. Cosmetic target is set to 0.\n" + ex); SetCosmeticWorldObjectTargetZero(director); } } private static void RunNormalCosmeticWorldObjectSetup(ValuableDirector director, int[] volumeIndex, List<ValuableVolume>[] volumeLists) { if (CosmeticWorldObjectSetupsField == null || CosmeticWorldObjectsSpawnCurveField == null) { return; } int num = InvokeIntMethod(CosmeticWorldObjectLevelLoopsGetMethod, director, 0); int num2 = InvokeIntMethod(CosmeticWorldObjectLevelLoopsClampedGetMethod, director, 0); int num3 = Mathf.Max(1, GetFieldValue<int>(CosmeticWorldObjectsLevelLoopField, director)); AnimationCurve fieldValue = GetFieldValue<AnimationCurve>(CosmeticWorldObjectsSpawnCurveField, director); if (fieldValue == null) { return; } for (int i = 0; i <= num2; i++) { float num4; if (i < num) { num4 = 1f; } else { int num5 = (((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelsCompleted : 0); num4 = (float)(num5 % num3) / (float)num3; } int num6 = Mathf.RoundToInt(fieldValue.Evaluate(num4) * 100f); int runManagerBadLuckCount = GetRunManagerBadLuckCount(); if (runManagerBadLuckCount > 0) { num6 += Mathf.RoundToInt((float)runManagerBadLuckCount * 20f); } if (Random.Range(0, 100) < num6) { object obj = PickCosmeticRarityByCurve(director, num4); if (obj != null) { InvokeSpawnCosmeticWorldObject(director, obj, volumeIndex, volumeLists); } } } if (GetFieldValue<int>(CosmeticWorldObjectTargetAmountField, director) <= 0) { SetRunManagerBadLuckCount(GetRunManagerBadLuckCount() + 1); } } private static object PickCosmeticRarityByCurve(ValuableDirector director, float curveTime) { IList fieldValue = GetFieldValue<IList>(CosmeticWorldObjectSetupsField, director); if (fieldValue == null || fieldValue.Count == 0) { return null; } object result = null; float num = -1f; foreach (object item in fieldValue) { if (item == null) { continue; } FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "chanceCurve"); FieldInfo fieldInfo2 = AccessTools.Field(item.GetType(), "rarity"); if (fieldInfo == null || fieldInfo2 == null) { continue; } object? value = fieldInfo.GetValue(item); AnimationCurve val = (AnimationCurve)((value is AnimationCurve) ? value : null); if (val == null) { continue; } int num2 = Mathf.RoundToInt(val.Evaluate(curveTime) * 100f); if (num2 > 0) { int num3 = Random.Range(0, num2); if ((float)num3 > num) { num = num3; result = fieldInfo2.GetValue(item); } } } return result; } private static void InvokeSpawnCosmeticWorldObjectByName(ValuableDirector director, string rarityName, int[] volumeIndex, List<ValuableVolume>[] volumeLists) { object cosmeticRarityEnumValue = GetCosmeticRarityEnumValue(rarityName); if (cosmeticRarityEnumValue != null) { InvokeSpawnCosmeticWorldObject(director, cosmeticRarityEnumValue, volumeIndex, volumeLists); } } private static object GetCosmeticRarityEnumValue(string rarityName) { if (SpawnCosmeticWorldObjectMethod == null) { return null; } ParameterInfo[] parameters = SpawnCosmeticWorldObjectMethod.GetParameters(); if (parameters == null || parameters.Length == 0 || parameters[0] == null || !parameters[0].ParameterType.IsEnum) { return null; } try { return Enum.Parse(parameters[0].ParameterType, rarityName); } catch { return null; } } private static void InvokeSpawnCosmeticWorldObject(ValuableDirector director, object rarityValue, int[] volumeIndex, List<ValuableVolume>[] volumeLists) { if (!(SpawnCosmeticWorldObjectMethod == null) && rarityValue != null) { SpawnCosmeticWorldObjectMethod.Invoke(director, new object[3] { rarityValue, volumeIndex, volumeLists }); } } private static int InvokeIntMethod(MethodInfo methodInfo, object instance, int fallbackValue) { if (methodInfo == null || instance == null) { return fallbackValue; } if (!(methodInfo.Invoke(instance, Array.Empty<object>()) is int result)) { return fallbackValue; } return result; } private static int GetRunManagerBadLuckCount() { if ((Object)(object)RunManager.instance == (Object)null || RunManagerCosmeticWorldObjectBadLuckCountField == null) { return 0; } if (!(RunManagerCosmeticWorldObjectBadLuckCountField.GetValue(RunManager.instance) is int result)) { return 0; } return result; } private static void SetRunManagerBadLuckCount(int value) { if (!((Object)(object)RunManager.instance == (Object)null) && !(RunManagerCosmeticWorldObjectBadLuckCountField == null)) { RunManagerCosmeticWorldObjectBadLuckCountField.SetValue(RunManager.instance, value); } } private static void SetCosmeticWorldObjectTargetZero(ValuableDirector director) { SetFieldValue(CosmeticWorldObjectTargetAmountField, director, 0); RpcTargetAmount(director, "CosmeticWorldObjectTargetSetRPC", 0); IncrementIntField(CosmeticWorldObjectSpawnPlayerReadyField, director); } private static bool IsMultiplayerRoomActive() { return (Object)(object)GameManager.instance != (Object)null && GameManager.instance.gameMode == 1 && PhotonNetwork.CurrentRoom != null; } private static void IncrementIntField(FieldInfo fieldInfo, object instance) { if (!(fieldInfo == null) && instance != null) { int fieldValue = GetFieldValue<int>(fieldInfo, instance); SetFieldValue(fieldInfo, instance, fieldValue + 1); } } private static string GetFieldValueAsString(FieldInfo fieldInfo, object instance) { if (fieldInfo == null || instance == null) { return string.Empty; } object value = fieldInfo.GetValue(instance); return (value == null) ? string.Empty : value.ToString(); } private static T GetFieldValue<T>(FieldInfo fieldInfo, object instance) { if (fieldInfo == null || instance == null) { return default(T); } object value = fieldInfo.GetValue(instance); if (value == null) { return default(T); } return (T)value; } private static void SetFieldValue(FieldInfo fieldInfo, object instance, object value) { if (!(fieldInfo == null) && instance != null) { fieldInfo.SetValue(instance, value); } } } }