Decompiled source of NewtLoot v1.0.0

NewtLoot.dll

Decompiled 5 hours 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("NewtLoot")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+2c9df6021f05456ceaf4c59fa68e57267370a718")]
[assembly: AssemblyProduct("NewtLoot")]
[assembly: AssemblyTitle("NewtLoot")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NewtLoot
{
	[BepInPlugin("com.creeper2002.newtloot", "Newt Loot", "0.1.2")]
	[BepInProcess("Risk of Rain 2.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private sealed class AspectEntry
		{
			public readonly string DisplayName;

			public readonly string InternalName;

			public readonly ConfigEntry<float> Weight;

			public AspectEntry(string displayName, string internalName, ConfigEntry<float> weight)
			{
				DisplayName = displayName;
				InternalName = internalName;
				Weight = weight;
			}
		}

		public const string PluginGuid = "com.creeper2002.newtloot";

		public const string PluginName = "Newt Loot";

		public const string PluginVersion = "0.1.2";

		internal static ManualLogSource Log;

		private readonly List<AspectEntry> aspects = new List<AspectEntry>();

		private readonly HashSet<int> rewardedBodies = new HashSet<int>();

		private bool rewardSpawnInProgress;

		private void Awake()
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			BindAspect("Her Biting Embrace", "EliteIceEquipment", 16f);
			BindAspect("Ifrit's Distinction", "EliteFireEquipment", 16f);
			BindAspect("Silence Between Two Strikes", "EliteLightningEquipment", 14f);
			BindAspect("His Reassurance", "EliteEarthEquipment", 13f);
			BindAspect("Spectral Circlet", "EliteHauntedEquipment", 11f);
			BindAspect("N'kuhana's Retort", "ElitePoisonEquipment", 9f);
			BindAspect("Aurelionite's Blessing", "EliteAurelioniteEquipment", 8f);
			BindAspect("His Spiteful Boon", "EliteBeadEquipment", 6f);
			BindAspect("Of One Mind", "EliteCollectiveEquipment", 5f);
			BindAspect("Shared Design", "EliteLunarEquipment", 2f);
			GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeathGlobal;
			CharacterBody.OnDeathStart += new hook_OnDeathStart(OnCharacterBodyDeathStart);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Newt Loot 0.1.2 loaded. Newt will drop one independently rolled Elite Equipment per player.");
		}

		private void OnDestroy()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeathGlobal;
			CharacterBody.OnDeathStart -= new hook_OnDeathStart(OnCharacterBodyDeathStart);
		}

		private void BindAspect(string displayName, string internalName, float defaultWeight)
		{
			string text = MakeConfigKey(displayName);
			ConfigEntry<float> weight = ((BaseUnityPlugin)this).Config.Bind<float>("Aspect Weights", text, defaultWeight, "Relative drop weight for " + displayName + ". Weights are normalized automatically. Set to 0 to disable this drop.");
			aspects.Add(new AspectEntry(displayName, internalName, weight));
		}

		private static string MakeConfigKey(string displayName)
		{
			return new string(displayName.Where(char.IsLetterOrDigit).ToArray());
		}

		private void OnCharacterDeathGlobal(DamageReport report)
		{
			if (NetworkServer.active && report != null && !((Object)(object)report.victimBody == (Object)null))
			{
				CharacterBody victimBody = report.victimBody;
				if (IsNewt(victimBody))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Detected Newt via GlobalEventManager death event: body='" + ((Object)victimBody).name + "', token='" + victimBody.baseNameToken + "'."));
					TryRewardNewt(victimBody, "GlobalEventManager");
				}
			}
		}

		private void OnCharacterBodyDeathStart(orig_OnDeathStart orig, CharacterBody self)
		{
			if (NetworkServer.active && (Object)(object)self != (Object)null && IsNewt(self))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Detected Newt via CharacterBody.OnDeathStart: body='" + ((Object)self).name + "', token='" + self.baseNameToken + "'."));
				TryRewardNewt(self, "OnDeathStart");
			}
			orig.Invoke(self);
		}

		private static bool IsNewt(CharacterBody body)
		{
			if ((Object)(object)body == (Object)null)
			{
				return false;
			}
			string obj = ((Object)body).name ?? string.Empty;
			string text = body.baseNameToken ?? string.Empty;
			if (obj.IndexOf("ShopkeeperBody", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("SHOPKEEPER", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return true;
		}

		private void TryRewardNewt(CharacterBody body, string source)
		{
			if ((Object)(object)body == (Object)null || rewardSpawnInProgress)
			{
				return;
			}
			int instanceID = ((Object)body).GetInstanceID();
			if (rewardedBodies.Contains(instanceID))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Ignoring duplicate Newt death callback from {source} for instance {instanceID}.");
				return;
			}
			rewardSpawnInProgress = true;
			try
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Spawning Newt rewards from {source} for instance {instanceID}.");
				SpawnNewtRewards(body);
				rewardedBodies.Add(instanceID);
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to spawn Newt rewards from {source}: {arg}");
			}
			finally
			{
				rewardSpawnInProgress = false;
			}
		}

		private void SpawnNewtRewards(CharacterBody newtBody)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			int num = Math.Max(1, PlayerCharacterMasterController.instances.Count);
			List<(AspectEntry, PickupIndex)> list = BuildCurrentPool();
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Newt reward calculation: playerCount={num}, validAspectCount={list.Count}.");
			if (list.Count == 0)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Newt died, but no enabled/available Elite Equipment had a positive weight. No rewards were spawned.");
				return;
			}
			Transform transform = ((Component)newtBody).gameObject.transform;
			Vector3 forward = transform.forward;
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude < 0.01f)
			{
				forward = Vector3.forward;
			}
			((Vector3)(ref forward)).Normalize();
			Vector3 val = transform.position + Vector3.up * 1.8f + forward * 1.2f;
			for (int i = 0; i < num; i++)
			{
				(AspectEntry, PickupIndex) tuple = RollAspect(list);
				float num2 = ((num <= 1) ? 0.5f : ((float)i / (float)(num - 1)));
				Vector3 val2 = Quaternion.AngleAxis(Mathf.Lerp(-35f, 35f, num2), Vector3.up) * forward * 16f + Vector3.up * 15f;
				PickupDropletController.CreatePickupDroplet(tuple.Item2, val, val2);
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Newt reward {i + 1}/{num}: {tuple.Item1.DisplayName}");
			}
		}

		private List<(AspectEntry aspect, PickupIndex pickup)> BuildCurrentPool()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			List<(AspectEntry, PickupIndex)> list = new List<(AspectEntry, PickupIndex)>();
			foreach (AspectEntry aspect in aspects)
			{
				if (aspect.Weight.Value <= 0f)
				{
					continue;
				}
				EquipmentIndex val = EquipmentCatalog.FindEquipmentIndex(aspect.InternalName);
				if ((int)val == -1)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Skipping " + aspect.DisplayName + ": equipment '" + aspect.InternalName + "' was not found."));
					continue;
				}
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(val);
				if (!((Object)(object)equipmentDef == (Object)null) && (!((Object)(object)equipmentDef.requiredExpansion != (Object)null) || !((Object)(object)Run.instance != (Object)null) || Run.instance.IsExpansionEnabled(equipmentDef.requiredExpansion)))
				{
					PickupIndex val2 = PickupCatalog.FindPickupIndex(val);
					if (val2 == PickupIndex.none)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Skipping " + aspect.DisplayName + ": no PickupIndex exists for '" + aspect.InternalName + "'."));
					}
					else
					{
						list.Add((aspect, val2));
					}
				}
			}
			return list;
		}

		private (AspectEntry aspect, PickupIndex pickup) RollAspect(List<(AspectEntry aspect, PickupIndex pickup)> pool)
		{
			float num = 0f;
			foreach (var item in pool)
			{
				num += Math.Max(0f, item.aspect.Weight.Value);
			}
			if (num <= 0f)
			{
				return pool[Random.Range(0, pool.Count)];
			}
			float num2 = Random.Range(0f, num);
			foreach (var item2 in pool)
			{
				num2 -= Math.Max(0f, item2.aspect.Weight.Value);
				if (num2 <= 0f)
				{
					return item2;
				}
			}
			return pool[pool.Count - 1];
		}
	}
}