Decompiled source of StartWithRandomWeapon v1.2.0

StartWithRandomWeapon.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RepoAPI.Game;
using RepoAPI.Items;
using StartWithRandomWeapon.Configuration;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Osmar Briones")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+0ae6ccc16c5a267f51c9999c5a7681f7c5e8233a")]
[assembly: AssemblyProduct("StartWithRandomWeapon")]
[assembly: AssemblyTitle("StartWithRandomWeapon")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class GameKeyEnumExtensions
{
	public static string GetGameKey<T>(this T value) where T : Enum
	{
		return typeof(T).GetMember(value.ToString()).First().GetCustomAttribute<GameKeyAttribute>()?.Key ?? value.ToString();
	}

	public static bool TryFromGameKey<T>(string key, out T result) where T : Enum
	{
		foreach (T item in Enum.GetValues(typeof(T)).Cast<T>())
		{
			if (item.GetGameKey().Equals(key, StringComparison.OrdinalIgnoreCase))
			{
				result = item;
				return true;
			}
		}
		result = default(T);
		return false;
	}

	public static string[] GetAllGameKeys<T>() where T : Enum
	{
		return (from T v in Enum.GetValues(typeof(T))
			select v.GetGameKey()).ToArray();
	}

	public static T FromGameKey<T>(string key) where T : Enum
	{
		if (TryFromGameKey<T>(key, out var result))
		{
			return result;
		}
		throw new ArgumentException("Invalid game key '" + key + "' for enum " + typeof(T).Name);
	}
}
namespace RepoAPI.Game
{
	[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
	public sealed class GameKeyAttribute(string key) : Attribute()
	{
		public string Key { get; } = key;
	}
}
namespace RepoAPI.Items
{
	public enum ItemName
	{
		[GameKey("Item Cart Cannon")]
		CartCannon,
		[GameKey("Item Cart Laser")]
		CartLaser,
		[GameKey("Item Cart Medium")]
		CartMedium,
		[GameKey("Item Cart Small")]
		CartSmall,
		[GameKey("Item Drone Battery")]
		DroneBattery,
		[GameKey("Item Drone Feather")]
		DroneFeather,
		[GameKey("Item Drone Indestructible")]
		DroneIndestructible,
		[GameKey("Item Drone Torque")]
		DroneTorque,
		[GameKey("Item Drone Zero Gravity")]
		DroneZeroGravity,
		[GameKey("Item Duck Bucket")]
		DuckBucket,
		[GameKey("Item Extraction Tracker")]
		ExtractionTracker,
		[GameKey("Item Grenade Duct Taped")]
		GrenadeDuctTaped,
		[GameKey("Item Grenade Explosive")]
		GrenadeExplosive,
		[GameKey("Item Grenade Human")]
		GrenadeHuman,
		[GameKey("Item Grenade Shockwave")]
		GrenadeShockwave,
		[GameKey("Item Grenade Stun")]
		GrenadeStun,
		[GameKey("Item Gun Handgun")]
		GunHandgun,
		[GameKey("Item Gun Laser")]
		GunLaser,
		[GameKey("Item Gun Shockwave")]
		GunShockwave,
		[GameKey("Item Gun Shotgun")]
		GunShotgun,
		[GameKey("Item Gun Stun")]
		GunStun,
		[GameKey("Item Gun Tranq")]
		GunTranq,
		[GameKey("Item Health Pack Large")]
		HealthPackLarge,
		[GameKey("Item Health Pack Medium")]
		HealthPackMedium,
		[GameKey("Item Health Pack Small")]
		HealthPackSmall,
		[GameKey("Item Melee Baseball Bat")]
		MeleeBaseballBat,
		[GameKey("Item Melee Frying Pan")]
		MeleeFryingPan,
		[GameKey("Item Melee Inflatable Hammer")]
		MeleeInflatableHammer,
		[GameKey("Item Melee Sledge Hammer")]
		MeleeSledgeHammer,
		[GameKey("Item Melee Stun Baton")]
		MeleeStunBaton,
		[GameKey("Item Melee Sword")]
		MeleeSword,
		[GameKey("Item Mine Explosive")]
		MineExplosive,
		[GameKey("Item Mine Shockwave")]
		MineShockwave,
		[GameKey("Item Mine Stun")]
		MineStun,
		[GameKey("Item Orb Zero Gravity")]
		OrbZeroGravity,
		[GameKey("Item Phase Bridge")]
		PhaseBridge,
		[GameKey("Item Leaf Blower")]
		LeafBlower,
		[GameKey("Item Power Crystal")]
		PowerCrystal,
		[GameKey("Item ReviveItem")]
		ReviveItem,
		[GameKey("Item Rubber Duck")]
		RubberDuck,
		[GameKey("Item Staff Torque")]
		StaffTorque,
		[GameKey("Item Staff Void")]
		StaffVoid,
		[GameKey("Item Staff Zero Gravity")]
		StaffZeroGravity,
		[GameKey("Item Vehicle Semiscooter")]
		VehicleSemiscooter,
		[GameKey("Item Vehicle Semiscooter Small")]
		VehicleSemiscooterSmall,
		[GameKey("Item WalkieTalkieBox")]
		WalkieTalkieBox,
		[GameKey("Item Upgrade Death Head Battery")]
		UpgradeDeathHeadBattery,
		[GameKey("Item Upgrade Map Player Count")]
		UpgradeMapPlayerCount,
		[GameKey("Item Upgrade Player Crouch Rest")]
		UpgradePlayerCrouchRest,
		[GameKey("Item Upgrade Player Energy")]
		UpgradePlayerEnergy,
		[GameKey("Item Upgrade Player Extra Jump")]
		UpgradePlayerExtraJump,
		[GameKey("Item Upgrade Player Grab Range")]
		UpgradePlayerGrabRange,
		[GameKey("Item Upgrade Player Grab Strength")]
		UpgradePlayerGrabStrength,
		[GameKey("Item Upgrade Player Health")]
		UpgradePlayerHealth,
		[GameKey("Item Upgrade Player Sprint Speed")]
		UpgradePlayerSprintSpeed,
		[GameKey("Item Upgrade Player Tumble Climb")]
		UpgradePlayerTumbleClimb,
		[GameKey("Item Upgrade Player Tumble Launch")]
		UpgradePlayerTumbleLaunch,
		[GameKey("Item Upgrade Player Tumble Wings")]
		UpgradePlayerTumbleWings,
		[GameKey("Item Valuable Tracker")]
		ValuableTracker,
		[GameKey("Item Gun Revolver")]
		GunRevolver,
		[GameKey("Item Melee Whip")]
		MeleeWhip,
		[GameKey("Item Orb Battery")]
		OrbBattery
	}
}
namespace StartWithRandomWeapon
{
	[BepInPlugin("com.osmarbriones.startwithrandomweapon", "StartWithRandomWeapon", "1.2.0")]
	public class StartWithRandomWeaponPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.osmarbriones.startwithrandomweapon";

		public const string PluginName = "StartWithRandomWeapon";

		public const string PluginVersion = "1.2.0";

		internal Harmony? Harmony { get; set; }

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			StartWithRandomWeaponConfig.Initialize(((BaseUnityPlugin)this).Config);
			Harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			Harmony.PatchAll();
			Logger.LogInfo((object)"StartWithRandomWeapon 1.2.0 loaded!");
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace StartWithRandomWeapon.Patches
{
	[HarmonyPatch(typeof(RunManager), "SetRunLevel")]
	internal static class RunManager_SetRunLevel_Patch
	{
		private static void Postfix(RunManager __instance)
		{
			if (!CanSpawn(__instance))
			{
				return;
			}
			StartWithRandomWeaponConfig.Reload();
			if (StartWithRandomWeaponConfig.Enabled)
			{
				StatsManager instance = StatsManager.instance;
				List<string> list = BuildAvailableList(instance);
				if (list.Count == 0)
				{
					StartWithRandomWeaponPlugin.Logger.LogInfo((object)"No configured starting items are valid/present.");
					return;
				}
				int spawnCount = GetSpawnCount(list.Count);
				List<string> list2 = SelectItems(list, spawnCount);
				PurchaseItems(instance, list2);
				StartWithRandomWeaponPlugin.Logger.LogInfo((object)string.Format("Spawned {0} unique starting item(s): {1}", list2.Count, string.Join(", ", list2)));
			}
		}

		private static bool CanSpawn(RunManager runManager)
		{
			if (runManager.levelsCompleted != 0)
			{
				return false;
			}
			return (Object)(object)StatsManager.instance != (Object)null;
		}

		private static List<string> BuildAvailableList(StatsManager stats)
		{
			return (from key in StartWithRandomWeaponConfig.GetEnabledWeaponKeys()
				where stats.itemDictionary.ContainsKey(key)
				select key).Where(delegate(string key)
			{
				Item val = stats.itemDictionary[key];
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				if (!val.physicalItem)
				{
					return false;
				}
				if (val.disabled)
				{
					return false;
				}
				return (!stats.itemsPurchased.ContainsKey(key) || stats.itemsPurchased[key] <= 0) ? true : false;
			}).Distinct().ToList();
		}

		private static int GetSpawnCount(int availableCount)
		{
			if (StartWithRandomWeaponConfig.SpawnOnePerPlayer)
			{
				int num = 1;
				if ((Object)(object)GameDirector.instance != (Object)null && GameDirector.instance.PlayerList != null)
				{
					num = GameDirector.instance.PlayerList.Count;
				}
				if (num < 1)
				{
					num = 1;
				}
				if (num > availableCount)
				{
					num = availableCount;
				}
				return num;
			}
			int num2 = StartWithRandomWeaponConfig.WeaponsToSpawn;
			if (num2 < 1)
			{
				num2 = 1;
			}
			if (num2 > 50)
			{
				num2 = 50;
			}
			if (num2 > availableCount)
			{
				num2 = availableCount;
			}
			return num2;
		}

		private static List<string> SelectItems(List<string> available, int count)
		{
			Shuffle(available);
			return available.Take(count).ToList();
		}

		private static void PurchaseItems(StatsManager statsManager, List<string> selectedItems)
		{
			foreach (string selectedItem in selectedItems)
			{
				statsManager.ItemPurchase(selectedItem);
			}
		}

		private static void Shuffle(List<string> list)
		{
			for (int num = list.Count - 1; num > 0; num--)
			{
				int num2 = Random.Range(0, num + 1);
				if (num2 != num)
				{
					int index = num;
					int index2 = num2;
					string value = list[num2];
					string value2 = list[num];
					list[index] = value;
					list[index2] = value2;
				}
			}
		}
	}
}
namespace StartWithRandomWeapon.Configuration
{
	internal static class StartWithRandomWeaponConfig
	{
		private static ConfigFile? configFile;

		private static ConfigEntry<bool>? enabled;

		private static ConfigEntry<int>? weaponsToSpawn;

		private static ConfigEntry<bool>? spawnOnePerPlayer;

		private static ConfigEntry<bool>? resetWeaponsToDefault;

		private static ConfigEntry<bool>? disableAllWeapons;

		private static readonly Dictionary<string, ConfigEntry<bool>> weaponToggles = new Dictionary<string, ConfigEntry<bool>>();

		private static readonly (ItemName Item, bool Enabled)[] weaponDefaults = new(ItemName, bool)[20]
		{
			(ItemName.RubberDuck, true),
			(ItemName.MeleeInflatableHammer, true),
			(ItemName.MeleeFryingPan, true),
			(ItemName.MeleeSword, true),
			(ItemName.MeleeStunBaton, false),
			(ItemName.MeleeBaseballBat, false),
			(ItemName.MeleeWhip, true),
			(ItemName.MeleeSledgeHammer, false),
			(ItemName.GunShockwave, true),
			(ItemName.GunStun, true),
			(ItemName.GunHandgun, true),
			(ItemName.GunRevolver, false),
			(ItemName.GunTranq, true),
			(ItemName.GunLaser, false),
			(ItemName.GunShotgun, false),
			(ItemName.StaffZeroGravity, true),
			(ItemName.StaffTorque, false),
			(ItemName.StaffVoid, false),
			(ItemName.CartCannon, false),
			(ItemName.CartLaser, false)
		};

		internal static bool Enabled => enabled?.Value ?? true;

		internal static int WeaponsToSpawn => weaponsToSpawn?.Value ?? 1;

		internal static bool SpawnOnePerPlayer => spawnOnePerPlayer?.Value ?? false;

		internal static void Initialize(ConfigFile config)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Expected O, but got Unknown
			configFile = config ?? throw new ArgumentNullException("config");
			enabled = config.Bind<bool>("General", "Enabled", true, new ConfigDescription("Enable or disable this mod.", (AcceptableValueBase)null, Array.Empty<object>()));
			weaponsToSpawn = config.Bind<int>("General", "WeaponsToSpawn", 3, new ConfigDescription("Number of starting weapons to spawn (ignored if SpawnOnePerPlayer is true).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
			spawnOnePerPlayer = config.Bind<bool>("General", "SpawnOnePerPlayer", true, new ConfigDescription("If true, ignore WeaponsToSpawn and spawn one starting weapon per current player.", (AcceptableValueBase)null, Array.Empty<object>()));
			resetWeaponsToDefault = config.Bind<bool>("General", "ResetWeaponsToDefault", false, new ConfigDescription("Set to true to restore every weapon toggle to its default value. The switch turns itself off afterwards.", (AcceptableValueBase)null, Array.Empty<object>()));
			resetWeaponsToDefault.SettingChanged += OnResetWeaponsToDefaultChanged;
			disableAllWeapons = config.Bind<bool>("General", "DisableAllWeapons", false, new ConfigDescription("Set to true to turn every weapon toggle off, so you can enable only the ones you want. The switch turns itself off afterwards.", (AcceptableValueBase)null, Array.Empty<object>()));
			disableAllWeapons.SettingChanged += OnDisableAllWeaponsChanged;
			(ItemName, bool)[] array = weaponDefaults;
			for (int i = 0; i < array.Length; i++)
			{
				(ItemName, bool) tuple = array[i];
				ItemName item = tuple.Item1;
				bool item2 = tuple.Item2;
				string gameKey = item.GetGameKey();
				weaponToggles[gameKey] = config.Bind<bool>("Weapons", gameKey, item2, new ConfigDescription("Enable spawning " + gameKey + " weapon at start.", (AcceptableValueBase)null, Array.Empty<object>()));
			}
			StartWithRandomWeaponPlugin.Logger.LogInfo((object)($"Config loaded: Enabled = {Enabled}, WeaponsToSpawn = {WeaponsToSpawn}, " + $"SpawnOnePerPlayer = {SpawnOnePerPlayer}, " + "WeaponToggles = " + string.Join(", ", weaponToggles.Select<KeyValuePair<string, ConfigEntry<bool>>, string>((KeyValuePair<string, ConfigEntry<bool>> kvp) => $"{kvp.Key} = {kvp.Value.Value}"))));
		}

		internal static void Reload()
		{
			ConfigFile? obj = configFile;
			if (obj != null)
			{
				obj.Reload();
			}
		}

		internal static List<string> GetEnabledWeaponKeys()
		{
			return (from kvp in weaponToggles
				where kvp.Value.Value
				select kvp.Key).ToList();
		}

		private static void OnResetWeaponsToDefaultChanged(object sender, EventArgs e)
		{
			ConfigEntry<bool> val = resetWeaponsToDefault;
			if (val != null && val.Value)
			{
				(ItemName, bool)[] array = weaponDefaults;
				for (int i = 0; i < array.Length; i++)
				{
					var (value, value2) = array[i];
					weaponToggles[value.GetGameKey()].Value = value2;
				}
				resetWeaponsToDefault.Value = false;
				ConfigFile? obj = configFile;
				if (obj != null)
				{
					obj.Save();
				}
				StartWithRandomWeaponPlugin.Logger.LogInfo((object)"All weapon toggles were reset to their defaults.");
			}
		}

		private static void OnDisableAllWeaponsChanged(object sender, EventArgs e)
		{
			ConfigEntry<bool> val = disableAllWeapons;
			if (val == null || !val.Value)
			{
				return;
			}
			foreach (ConfigEntry<bool> value in weaponToggles.Values)
			{
				value.Value = false;
			}
			disableAllWeapons.Value = false;
			ConfigFile? obj = configFile;
			if (obj != null)
			{
				obj.Save();
			}
			StartWithRandomWeaponPlugin.Logger.LogInfo((object)"All weapon toggles were turned off.");
		}
	}
}