Decompiled source of RobsTweaks v2.1.0

RobsTweaks.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RobsTweaks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RobsTweaks")]
[assembly: AssemblyTitle("RobsTweaks")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RobsTweaks
{
	[BepInPlugin("com.rob.robstweaks", "RobsTweaks", "2.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static EventHandler <>9__25_1;

			public static EventHandler <>9__25_0;

			public static EventHandler <>9__25_2;

			public static IsDisabledDelegate <>9__26_0;

			public static IsDisabledDelegate <>9__27_0;

			internal void <Awake>b__25_1(object _, EventArgs __)
			{
				Tweaks.RefreshAllStats();
			}

			internal void <Awake>b__25_0(object _, EventArgs __)
			{
				Tweaks.RefreshAllStats();
			}

			internal void <Awake>b__25_2(object _, EventArgs __)
			{
				Tweaks.RefreshLootTables();
			}

			internal bool <Slider>b__26_0()
			{
				return Sync.IsGuest;
			}

			internal bool <IntSlider>b__27_0()
			{
				return Sync.IsGuest;
			}
		}

		public const string PluginGUID = "com.rob.robstweaks";

		public const string PluginName = "RobsTweaks";

		public const string PluginVersion = "2.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<float> GoldMultiplier;

		internal static ConfigEntry<float> XpMultiplier;

		internal static ConfigEntry<float> PriceMultiplier;

		internal static ConfigEntry<int> StartingGold;

		internal static ConfigEntry<float> InteractableMultiplier;

		internal static ConfigEntry<float> ChargeSpeedMultiplier;

		internal static ConfigEntry<float> PlayerDamage;

		internal static ConfigEntry<float> PlayerHealth;

		internal static ConfigEntry<float> PlayerMoveSpeed;

		internal static ConfigEntry<float> PlayerAttackSpeed;

		internal static ConfigEntry<int> ExtraJumps;

		internal static ConfigEntry<float> EnemySpawnRate;

		internal static ConfigEntry<float> EnemyHealth;

		internal static ConfigEntry<float> EnemyDamage;

		internal static ConfigEntry<int> BossExtraItems;

		internal static ConfigEntry<float> ChestBonusDropChance;

		internal static ConfigEntry<float> CommonWeight;

		internal static ConfigEntry<float> UncommonWeight;

		internal static ConfigEntry<float> LegendaryWeight;

		internal static ConfigEntry<float> BossItemWeight;

		internal static ConfigEntry<float> LunarWeight;

		private void Awake()
		{
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModSettingsManager.SetModDescription("Rob's gameplay tweaks. Every setting can be changed mid-run. In multiplayer, only the host's settings are used.");
			GoldMultiplier = Slider("Economy", "Gold multiplier", 1.5f, 0f, 20f, 0.25f, "Multiplies all gold you earn.");
			XpMultiplier = Slider("Economy", "XP multiplier", 1f, 0f, 20f, 0.25f, "Multiplies all experience your team earns.");
			PriceMultiplier = Slider("Economy", "Price multiplier", 1f, 0f, 5f, 0.05f, "Multiplies gold prices of chests, shrines, drones, etc. 0 = free. Applies to things spawned after you change it (i.e. next stage).");
			StartingGold = IntSlider("Economy", "Starting gold", 0, 0, 5000, "Extra gold each player gets at the start of a run.");
			InteractableMultiplier = Slider("Stage", "Interactable multiplier", 1.5f, 0f, 20f, 0.25f, "More chests, shrines, drones, etc. Applies from the next stage.");
			ChargeSpeedMultiplier = Slider("Stage", "Teleporter charge speed", 2f, 0.25f, 20f, 0.25f, "How fast the teleporter, moon pillars and void cells charge.");
			PlayerDamage = Slider("Player", "Damage multiplier", 1f, 0.1f, 20f, 0.1f, "Multiplies player damage.");
			PlayerHealth = Slider("Player", "Health multiplier", 1f, 0.1f, 20f, 0.1f, "Multiplies player max health.");
			PlayerMoveSpeed = Slider("Player", "Move speed multiplier", 1f, 0.1f, 5f, 0.1f, "Multiplies player movement speed.");
			PlayerAttackSpeed = Slider("Player", "Attack speed multiplier", 1f, 0.1f, 5f, 0.1f, "Multiplies player attack speed.");
			ExtraJumps = IntSlider("Player", "Extra jumps", 0, 0, 10, "Extra mid-air jumps.");
			EnemySpawnRate = Slider("Enemies", "Spawn rate multiplier", 1f, 0f, 10f, 0.25f, "How many monsters the game can afford to send at you. 0 = (almost) nothing spawns during the stage.");
			EnemyHealth = Slider("Enemies", "Health multiplier", 1f, 0.1f, 20f, 0.1f, "Multiplies enemy max health.");
			EnemyDamage = Slider("Enemies", "Damage multiplier", 1f, 0.1f, 20f, 0.1f, "Multiplies enemy damage.");
			BossExtraItems = IntSlider("Loot", "Extra teleporter boss items", 0, 0, 20, "Extra items dropped when you beat the teleporter boss.");
			ChestBonusDropChance = Slider("Loot", "Chest bonus drop chance (%)", 0f, 0f, 100f, 5f, "Chance a chest drops a second copy of its item.");
			CommonWeight = Slider("Loot", "Common (white) weight", 1f, 0f, 100f, 0.5f, "How likely white items are, relative to normal.");
			UncommonWeight = Slider("Loot", "Uncommon (green) weight", 1f, 0f, 100f, 0.5f, "How likely green items are, relative to normal.");
			LegendaryWeight = Slider("Loot", "Legendary (red) weight", 1f, 0f, 100f, 0.5f, "How likely red items are, relative to normal.");
			BossItemWeight = Slider("Loot", "Boss (yellow) weight", 1f, 0f, 100f, 0.5f, "How likely yellow items are, relative to normal.");
			LunarWeight = Slider("Loot", "Lunar (blue) weight", 1f, 0f, 100f, 0.5f, "How likely lunar items are, relative to normal.");
			ConfigEntryBase[] array = (ConfigEntryBase[])(object)new ConfigEntryBase[6]
			{
				(ConfigEntryBase)PlayerDamage,
				(ConfigEntryBase)PlayerHealth,
				(ConfigEntryBase)PlayerMoveSpeed,
				(ConfigEntryBase)PlayerAttackSpeed,
				(ConfigEntryBase)EnemyHealth,
				(ConfigEntryBase)EnemyDamage
			};
			for (int i = 0; i < array.Length; i++)
			{
				((ConfigEntry<float>)(object)array[i]).SettingChanged += delegate
				{
					Tweaks.RefreshAllStats();
				};
			}
			ExtraJumps.SettingChanged += delegate
			{
				Tweaks.RefreshAllStats();
			};
			ConfigEntry<float>[] array2 = new ConfigEntry<float>[5] { CommonWeight, UncommonWeight, LegendaryWeight, BossItemWeight, LunarWeight };
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i].SettingChanged += delegate
				{
					Tweaks.RefreshLootTables();
				};
			}
			Tweaks.Init();
			Sync.Init();
			Harmony val = new Harmony("com.rob.robstweaks");
			Type[] nestedTypes = typeof(Tweaks).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
			foreach (Type type in nestedTypes)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0)
				{
					try
					{
						val.PatchAll(type);
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)("Couldn't apply " + type.Name + ": " + ex.Message));
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"RobsTweaks 2.1.0 loaded.");
		}

		private ConfigEntry<float> Slider(string section, string key, float def, float min, float max, float step, string desc)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			ConfigEntry<float> obj = ((BaseUnityPlugin)this).Config.Bind<float>(section, key, def, desc);
			StepSliderConfig val = new StepSliderConfig
			{
				min = min,
				max = max,
				increment = step
			};
			object obj2 = <>c.<>9__26_0;
			if (obj2 == null)
			{
				IsDisabledDelegate val2 = () => Sync.IsGuest;
				<>c.<>9__26_0 = val2;
				obj2 = (object)val2;
			}
			((BaseOptionConfig)val).checkIfDisabled = (IsDisabledDelegate)obj2;
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(obj, val));
			return obj;
		}

		private ConfigEntry<int> IntSlider(string section, string key, int def, int min, int max, string desc)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0050: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			ConfigEntry<int> obj = ((BaseUnityPlugin)this).Config.Bind<int>(section, key, def, desc);
			IntSliderConfig val = new IntSliderConfig
			{
				min = min,
				max = max
			};
			object obj2 = <>c.<>9__27_0;
			if (obj2 == null)
			{
				IsDisabledDelegate val2 = () => Sync.IsGuest;
				<>c.<>9__27_0 = val2;
				obj2 = (object)val2;
			}
			((BaseOptionConfig)val).checkIfDisabled = (IsDisabledDelegate)obj2;
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(obj, val));
			return obj;
		}
	}
	internal static class Sync
	{
		private class SettingsMessage : INetMessage, ISerializableObject
		{
			public float[] f;

			public int[] n;

			public void Serialize(NetworkWriter w)
			{
				w.Write(f.Length);
				float[] array = f;
				foreach (float num in array)
				{
					w.Write(num);
				}
				w.Write(n.Length);
				int[] array2 = n;
				foreach (int num2 in array2)
				{
					w.Write(num2);
				}
			}

			public void Deserialize(NetworkReader r)
			{
				f = new float[r.ReadInt32()];
				for (int i = 0; i < f.Length; i++)
				{
					f[i] = r.ReadSingle();
				}
				n = new int[r.ReadInt32()];
				for (int j = 0; j < n.Length; j++)
				{
					n[j] = r.ReadInt32();
				}
			}

			public void OnReceived()
			{
				Receive(f, n);
			}
		}

		private static ConfigEntry<float>[] floats;

		private static ConfigEntry<int>[] ints;

		private static float[] hostFloats;

		private static int[] hostInts;

		internal static bool IsGuest
		{
			get
			{
				if (NetworkClient.active)
				{
					return !NetworkServer.active;
				}
				return false;
			}
		}

		internal static void Init()
		{
			floats = new ConfigEntry<float>[18]
			{
				Plugin.GoldMultiplier,
				Plugin.XpMultiplier,
				Plugin.PriceMultiplier,
				Plugin.InteractableMultiplier,
				Plugin.ChargeSpeedMultiplier,
				Plugin.PlayerDamage,
				Plugin.PlayerHealth,
				Plugin.PlayerMoveSpeed,
				Plugin.PlayerAttackSpeed,
				Plugin.EnemySpawnRate,
				Plugin.EnemyHealth,
				Plugin.EnemyDamage,
				Plugin.ChestBonusDropChance,
				Plugin.CommonWeight,
				Plugin.UncommonWeight,
				Plugin.LegendaryWeight,
				Plugin.BossItemWeight,
				Plugin.LunarWeight
			};
			ints = new ConfigEntry<int>[3]
			{
				Plugin.StartingGold,
				Plugin.ExtraJumps,
				Plugin.BossExtraItems
			};
			NetworkingAPI.RegisterMessageType<SettingsMessage>();
			ConfigEntry<float>[] array = floats;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SettingChanged += delegate
				{
					Broadcast();
				};
			}
			ConfigEntry<int>[] array2 = ints;
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i].SettingChanged += delegate
				{
					Broadcast();
				};
			}
			Stage.onServerStageBegin += delegate
			{
				Broadcast();
			};
			NetworkUser.onNetworkUserLoadedSceneServer += delegate
			{
				Broadcast();
			};
			Run.onRunDestroyGlobal += delegate
			{
				hostFloats = null;
				hostInts = null;
			};
		}

		internal static float Get(ConfigEntry<float> entry)
		{
			if (IsGuest && hostFloats != null)
			{
				int num = Array.IndexOf(floats, entry);
				if (num >= 0 && num < hostFloats.Length)
				{
					return hostFloats[num];
				}
			}
			return entry.Value;
		}

		internal static int Get(ConfigEntry<int> entry)
		{
			if (IsGuest && hostInts != null)
			{
				int num = Array.IndexOf(ints, entry);
				if (num >= 0 && num < hostInts.Length)
				{
					return hostInts[num];
				}
			}
			return entry.Value;
		}

		private static void Broadcast()
		{
			if (NetworkServer.active)
			{
				NetMessageExtensions.Send((INetMessage)(object)new SettingsMessage
				{
					f = Array.ConvertAll(floats, (ConfigEntry<float> e) => e.Value),
					n = Array.ConvertAll(ints, (ConfigEntry<int> e) => e.Value)
				}, (NetworkDestination)1);
			}
		}

		internal static void Receive(float[] f, int[] n)
		{
			if (!NetworkServer.active)
			{
				hostFloats = f;
				hostInts = n;
				Tweaks.RefreshAllStats();
				Plugin.Log.LogInfo((object)"Received the host's RobsTweaks settings.");
			}
		}
	}
	internal static class Tweaks
	{
		private class Depth
		{
			[ThreadStatic]
			public static int gold;

			[ThreadStatic]
			public static int xp;

			[ThreadStatic]
			public static int price;

			[ThreadStatic]
			public static int loot;
		}

		[HarmonyPatch]
		private static class GoldPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(CharacterMaster)))
				{
					ParameterInfo[] parameters = declaredMethod.GetParameters();
					if (declaredMethod.Name.StartsWith("GiveMoney") && parameters.Length != 0 && parameters[0].ParameterType == typeof(uint))
					{
						yield return declaredMethod;
					}
				}
			}

			private static void Prefix(ref uint __0)
			{
				if (Depth.gold++ == 0)
				{
					__0 = (uint)Mathf.RoundToInt((float)__0 * Sync.Get(Plugin.GoldMultiplier));
				}
			}

			private static void Finalizer()
			{
				Depth.gold--;
			}
		}

		[HarmonyPatch(typeof(TeamManager), "GiveTeamExperience")]
		private static class XpPatch
		{
			private static void Prefix(ref ulong __1)
			{
				if (Depth.xp++ == 0)
				{
					__1 = (ulong)Math.Round((double)__1 * (double)Sync.Get(Plugin.XpMultiplier));
				}
			}

			private static void Finalizer()
			{
				Depth.xp--;
			}
		}

		[HarmonyPatch]
		private static class PricePatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(Run)))
				{
					if (declaredMethod.Name == "GetDifficultyScaledCost")
					{
						yield return declaredMethod;
					}
				}
			}

			private static void Prefix()
			{
				Depth.price++;
			}

			private static void Postfix(ref int __result)
			{
				if (Depth.price == 1)
				{
					__result = Mathf.Max(0, Mathf.RoundToInt((float)__result * Sync.Get(Plugin.PriceMultiplier)));
				}
			}

			private static void Finalizer()
			{
				Depth.price--;
			}
		}

		[HarmonyPatch(typeof(HoldoutZoneController), "Update")]
		private static class ChargePatch
		{
			private static readonly ConditionalWeakTable<HoldoutZoneController, StrongBox<float>> original = new ConditionalWeakTable<HoldoutZoneController, StrongBox<float>>();

			private static void Prefix(HoldoutZoneController __instance)
			{
				StrongBox<float> value = original.GetValue(__instance, (HoldoutZoneController z) => new StrongBox<float>(z.baseChargeDuration));
				__instance.baseChargeDuration = value.Value / Mathf.Max(0.01f, Sync.Get(Plugin.ChargeSpeedMultiplier));
			}
		}

		[HarmonyPatch(typeof(CombatDirector), "FixedUpdate")]
		private static class SpawnRatePatch
		{
			private static readonly ConditionalWeakTable<CombatDirector, StrongBox<float>> original = new ConditionalWeakTable<CombatDirector, StrongBox<float>>();

			private static void Prefix(CombatDirector __instance)
			{
				StrongBox<float> value = original.GetValue(__instance, (CombatDirector d) => new StrongBox<float>(d.creditMultiplier));
				__instance.creditMultiplier = value.Value * Sync.Get(Plugin.EnemySpawnRate);
			}
		}

		[HarmonyPatch(typeof(BossGroup), "DropRewards")]
		private static class BossRewardPatch
		{
			private static void Prefix(BossGroup __instance, out int __state)
			{
				__state = 0;
				TeleporterInteraction instance = TeleporterInteraction.instance;
				if (Object.op_Implicit((Object)(object)instance) && !((Object)(object)instance.bossGroup != (Object)(object)__instance))
				{
					__state = Sync.Get(Plugin.BossExtraItems);
					__instance.bonusRewardCount += __state;
				}
			}

			private static void Postfix(BossGroup __instance, int __state)
			{
				__instance.bonusRewardCount -= __state;
			}
		}

		[HarmonyPatch(typeof(ChestBehavior), "ItemDrop")]
		private static class ChestBonusPatch
		{
			private static void Prefix(ChestBehavior __instance, out UniquePickup __state)
			{
				//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)
				__state = __instance.currentPickup;
			}

			private static void Postfix(ChestBehavior __instance, UniquePickup __state)
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: 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_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: 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_00a6: 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)
				if (NetworkServer.active && ((UniquePickup)(ref __state)).isValid && !(Random.value * 100f >= Sync.Get(Plugin.ChestBonusDropChance)))
				{
					Transform val = (Object.op_Implicit((Object)(object)__instance.dropTransform) ? __instance.dropTransform : ((Component)__instance).transform);
					Vector3 val2 = Vector3.up * 20f + val.forward * 4f;
					Vector3 val3 = val.position + Vector3.up * 1.5f;
					CreatePickupInfo val4 = default(CreatePickupInfo);
					((CreatePickupInfo)(ref val4)).pickup = __state;
					val4.position = val3;
					val4.chest = __instance;
					PickupDropletController.CreatePickupDroplet(val4, val3, val2);
				}
			}
		}

		[HarmonyPatch]
		private static class RarityPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				foreach (MethodInfo declaredMethod in AccessTools.GetDeclaredMethods(typeof(BasicPickupDropTable)))
				{
					if (declaredMethod.Name == "Regenerate" || declaredMethod.Name == "RegenerateDropTable")
					{
						yield return declaredMethod;
					}
				}
			}

			private static void Prefix(BasicPickupDropTable __instance, out float[] __state)
			{
				__state = null;
				if (Depth.loot++ == 0)
				{
					__state = new float[7] { __instance.tier1Weight, __instance.tier2Weight, __instance.tier3Weight, __instance.bossWeight, __instance.lunarItemWeight, __instance.lunarCombinedWeight, __instance.lunarEquipmentWeight };
					__instance.tier1Weight *= Sync.Get(Plugin.CommonWeight);
					__instance.tier2Weight *= Sync.Get(Plugin.UncommonWeight);
					__instance.tier3Weight *= Sync.Get(Plugin.LegendaryWeight);
					__instance.bossWeight *= Sync.Get(Plugin.BossItemWeight);
					__instance.lunarItemWeight *= Sync.Get(Plugin.LunarWeight);
					__instance.lunarCombinedWeight *= Sync.Get(Plugin.LunarWeight);
					__instance.lunarEquipmentWeight *= Sync.Get(Plugin.LunarWeight);
					float num = 0f;
					float num2 = 0f;
					float[] array = __state;
					foreach (float num3 in array)
					{
						num += num3;
					}
					num2 = __instance.tier1Weight + __instance.tier2Weight + __instance.tier3Weight + __instance.bossWeight + __instance.lunarItemWeight + __instance.lunarCombinedWeight + __instance.lunarEquipmentWeight;
					if (num > 0f && num2 <= 0f)
					{
						__instance.tier1Weight = __state[0];
						__instance.tier2Weight = __state[1];
						__instance.tier3Weight = __state[2];
						__instance.bossWeight = __state[3];
						__instance.lunarItemWeight = __state[4];
						__instance.lunarCombinedWeight = __state[5];
						__instance.lunarEquipmentWeight = __state[6];
					}
				}
			}

			private static void Finalizer(BasicPickupDropTable __instance, float[] __state)
			{
				Depth.loot--;
				if (__state != null)
				{
					__instance.tier1Weight = __state[0];
					__instance.tier2Weight = __state[1];
					__instance.tier3Weight = __state[2];
					__instance.bossWeight = __state[3];
					__instance.lunarItemWeight = __state[4];
					__instance.lunarCombinedWeight = __state[5];
					__instance.lunarEquipmentWeight = __state[6];
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Action<SceneDirector> <>9__0_0;

			public static Action<Stage> <>9__0_1;

			public static StatHookEventHandler <>9__0_2;

			internal void <Init>b__0_0(SceneDirector director)
			{
				director.interactableCredit = Mathf.RoundToInt((float)director.interactableCredit * Sync.Get(Plugin.InteractableMultiplier));
			}

			internal void <Init>b__0_1(Stage stage)
			{
				if ((Object)(object)Run.instance == (Object)null || Run.instance.stageClearCount != 0 || Sync.Get(Plugin.StartingGold) <= 0)
				{
					return;
				}
				foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
				{
					if (Object.op_Implicit((Object)(object)instance.master))
					{
						CharacterMaster master = instance.master;
						master.money += (uint)Sync.Get(Plugin.StartingGold);
					}
				}
			}

			internal void <Init>b__0_2(CharacterBody body, StatHookEventArgs args)
			{
				if (Object.op_Implicit((Object)(object)body))
				{
					if (body.isPlayerControlled)
					{
						args.damageTotalMult *= Sync.Get(Plugin.PlayerDamage);
						args.healthTotalMult *= Sync.Get(Plugin.PlayerHealth);
						args.moveSpeedTotalMult *= Sync.Get(Plugin.PlayerMoveSpeed);
						args.attackSpeedTotalMult *= Sync.Get(Plugin.PlayerAttackSpeed);
						args.jumpCountAdd += Sync.Get(Plugin.ExtraJumps);
					}
					else if (IsEnemy(body))
					{
						args.healthTotalMult *= Sync.Get(Plugin.EnemyHealth);
						args.damageTotalMult *= Sync.Get(Plugin.EnemyDamage);
					}
				}
			}
		}

		private static readonly MethodInfo regenerateAll = AccessTools.Method(typeof(PickupDropTable), "RegenerateAll", new Type[1] { typeof(Run) }, (Type[])null);

		internal static void Init()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			SceneDirector.onPrePopulateSceneServer += delegate(SceneDirector director)
			{
				director.interactableCredit = Mathf.RoundToInt((float)director.interactableCredit * Sync.Get(Plugin.InteractableMultiplier));
			};
			Stage.onServerStageBegin += delegate
			{
				if ((Object)(object)Run.instance == (Object)null || Run.instance.stageClearCount != 0 || Sync.Get(Plugin.StartingGold) <= 0)
				{
					return;
				}
				foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
				{
					if (Object.op_Implicit((Object)(object)instance.master))
					{
						CharacterMaster master = instance.master;
						master.money += (uint)Sync.Get(Plugin.StartingGold);
					}
				}
			};
			object obj = <>c.<>9__0_2;
			if (obj == null)
			{
				StatHookEventHandler val = delegate(CharacterBody body, StatHookEventArgs args)
				{
					if (Object.op_Implicit((Object)(object)body))
					{
						if (body.isPlayerControlled)
						{
							args.damageTotalMult *= Sync.Get(Plugin.PlayerDamage);
							args.healthTotalMult *= Sync.Get(Plugin.PlayerHealth);
							args.moveSpeedTotalMult *= Sync.Get(Plugin.PlayerMoveSpeed);
							args.attackSpeedTotalMult *= Sync.Get(Plugin.PlayerAttackSpeed);
							args.jumpCountAdd += Sync.Get(Plugin.ExtraJumps);
						}
						else if (IsEnemy(body))
						{
							args.healthTotalMult *= Sync.Get(Plugin.EnemyHealth);
							args.damageTotalMult *= Sync.Get(Plugin.EnemyDamage);
						}
					}
				};
				<>c.<>9__0_2 = val;
				obj = (object)val;
			}
			RecalculateStatsAPI.GetStatCoefficients += (StatHookEventHandler)obj;
		}

		private static bool IsEnemy(CharacterBody body)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			TeamIndex val = (TeamIndex)((!Object.op_Implicit((Object)(object)body.teamComponent)) ? (-1) : ((int)body.teamComponent.teamIndex));
			if ((int)val != 2 && (int)val != 3)
			{
				return (int)val == 4;
			}
			return true;
		}

		internal static void RefreshAllStats()
		{
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstances))
				{
					readOnlyInstances.MarkAllStatsDirty();
				}
			}
		}

		internal static void RefreshLootTables()
		{
			if (!Object.op_Implicit((Object)(object)Run.instance) || !NetworkServer.active)
			{
				return;
			}
			regenerateAll?.Invoke(null, new object[1] { Run.instance });
			ChestBehavior[] array = Object.FindObjectsOfType<ChestBehavior>();
			foreach (ChestBehavior val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && !val.isChestOpened && Object.op_Implicit((Object)(object)val.dropTable))
				{
					val.Roll();
				}
			}
		}
	}
}