Decompiled source of RevampMySoul v1.0.2

RevampMySoul.dll

Decompiled 2 hours ago
using System;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using IL.RoR2;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
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("RevampMySoul")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+df4940c92dbb0f50d0a4dc7e6ecf93bbc98c27f5")]
[assembly: AssemblyProduct("RevampMySoul")]
[assembly: AssemblyTitle("RevampMySoul")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[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 RevampMySoul
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.FortressForce.RevampMySoul", "RevampMySoul", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.FortressForce.RevampMySoul";

		public const string PluginName = "RevampMySoul";

		public const string PluginVersion = "1.0.2";

		private static readonly FieldInfo FieldMonsterTeamInventory = typeof(MonsterTeamGainsItemsArtifactManager).GetField("monsterTeamInventory", BindingFlags.Static | BindingFlags.NonPublic);

		private static GameObject _hippoRezEffectPrefab;

		public static ManualLogSource InstanceLogger { get; private set; } = null;

		public static Plugin Instance { get; private set; } = null;

		public static ConfigEntry<bool> IsEnabled { get; private set; } = null;

		public static ConfigEntry<bool> RequireArtifactOfSoul { get; private set; } = null;

		public static ConfigEntry<bool> EnableWispSoulFire { get; private set; } = null;

		public static ConfigEntry<float> SoulLifetimeSeconds { get; private set; } = null;

		public static ConfigEntry<float> InvulnerabilityDuration { get; private set; } = null;

		public static ConfigEntry<bool> PlayDioSpawnEffect { get; private set; } = null;

		public static ConfigEntry<bool> GrantEvolutionItems { get; private set; } = null;

		public static ConfigEntry<bool> TransferEliteAffixes { get; private set; } = null;

		public static ConfigEntry<int> SoulExpReward { get; private set; } = null;

		public static ConfigEntry<int> DamageBoostPercentage { get; private set; } = null;

		public static ConfigEntry<bool> EnableDebugLogging { get; private set; } = null;

		public static Inventory MonsterTeamInventory
		{
			get
			{
				object? obj = FieldMonsterTeamInventory?.GetValue(null);
				return (Inventory)((obj is Inventory) ? obj : null);
			}
		}

		public static GameObject HippoRezEffectPrefab
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)_hippoRezEffectPrefab))
				{
					_hippoRezEffectPrefab = LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/HippoRezEffect");
				}
				return _hippoRezEffectPrefab;
			}
		}

		public void Awake()
		{
			Instance = this;
			InstanceLogger = ((BaseUnityPlugin)this).Logger;
			InitConfig();
			RiskOfOptionsIntegration.Init(IsEnabled, RequireArtifactOfSoul, EnableWispSoulFire, SoulLifetimeSeconds, InvulnerabilityDuration, GrantEvolutionItems, TransferEliteAffixes, SoulExpReward, DamageBoostPercentage, EnableDebugLogging);
			RegisterHooks();
			InstanceLogger.LogInfo((object)"RevampMySoul v1.0.2 initialized successfully.");
		}

		private void InitConfig()
		{
			IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Enabled", true, "Enables or disables the mod entirely.");
			RequireArtifactOfSoul = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Require Artifact Of Soul", true, "If true, soul enemies only spawn when Artifact of Soul is active. If false, souls spawn on monster death in any run.");
			EnableWispSoulFire = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Soul Properties", "Enable Wisp Soul Fire", false, "If true, attaches bright cyan wisp soul fire flames across the soul enemy's body. If false, uses the standard ghost appearance.");
			SoulLifetimeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("2. Soul Properties", "Soul Lifetime Seconds", 30f, "The duration in seconds before the spawned soul automatically dies on a timer.");
			InvulnerabilityDuration = ((BaseUnityPlugin)this).Config.Bind<float>("2. Soul Properties", "Spawn Invulnerability Seconds", 1f, "The duration in seconds of Dio's Best Friend invulnerability buff granted to the soul enemy upon spawning.");
			PlayDioSpawnEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Soul Properties", "Play Dio Spawn Effect", true, "If true, plays the Dio's Best Friend revival visual/sound effect when the soul spawns.");
			GrantEvolutionItems = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Soul Properties", "Grant Evolution Items", true, "If true and Artifact of Evolution is active, the soul is granted monster team items on spawn.");
			TransferEliteAffixes = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Soul Properties", "Transfer Elite Essence", true, "If true, defeated elite monsters transfer their elite affixes (Blazing, Overloading, Glacial, etc.) to their soul clone.");
			SoulExpReward = ((BaseUnityPlugin)this).Config.Bind<int>("2. Soul Properties", "Soul Exp Reward", 5, "Experience reward granted when defeating a soul enemy (allows mods like Early Bird Sacrifice to count kills).");
			DamageBoostPercentage = ((BaseUnityPlugin)this).Config.Bind<int>("2. Soul Properties", "Damage Boost Percentage", 0, "Optional damage bonus percentage for soul enemies (0 = 100% normal damage, 50 = +50% damage).");
			EnableDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("3. Debug", "Enable Debug Logging", false, "Enables verbose console logging for soul spawning, timer attachment, and item grants.");
		}

		private void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			GlobalEventManager.OnCharacterDeath += new Manipulator(OnCharacterDeathIL);
			GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(OnCharacterDeathGlobal);
			CharacterBody.UpdateHurtBoxesEnabled += new hook_UpdateHurtBoxesEnabled(OnCharacterBodyUpdateHurtBoxesEnabled);
			CharacterBody.Start += new hook_Start(OnCharacterBodyStart);
		}

		private void OnCharacterDeathIL(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, typeof(Artifacts), "get_wispOnDeath"),
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, typeof(RunArtifactManager), "IsArtifactEnabled")
			}))
			{
				val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool vanillaArtifactEnabled) => !IsEnabled.Value && vanillaArtifactEnabled));
				if (EnableDebugLogging.Value)
				{
					InstanceLogger.LogInfo((object)"[ILHook] Successfully hooked GlobalEventManager.OnCharacterDeath for vanilla wisp suppression.");
				}
			}
			else
			{
				InstanceLogger.LogWarning((object)"[ILHook] Failed to locate wispOnDeath check in GlobalEventManager.OnCharacterDeath!");
			}
		}

		private static bool IsSoulEnemy(CharacterBody body)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)body))
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)body.teamComponent) || (int)body.teamComponent.teamIndex != 2)
			{
				return false;
			}
			if (!Object.op_Implicit((Object)(object)body.master) || !Object.op_Implicit((Object)(object)body.master.inventory))
			{
				return false;
			}
			Inventory inventory = body.master.inventory;
			if (inventory.GetItemCountEffective(Items.Ghost) <= 0)
			{
				return inventory.GetItemCountEffective(Items.InvadingDoppelganger) > 0;
			}
			return true;
		}

		private void OnCharacterBodyStart(orig_Start orig, CharacterBody self)
		{
			orig.Invoke(self);
			if (IsEnabled.Value && EnableWispSoulFire.Value && Object.op_Implicit((Object)(object)self) && IsSoulEnemy(self) && !Object.op_Implicit((Object)(object)((Component)self).GetComponent<SoulFireEffectController>()))
			{
				((Component)self).gameObject.AddComponent<SoulFireEffectController>();
			}
		}

		private void OnCharacterBodyUpdateHurtBoxesEnabled(orig_UpdateHurtBoxesEnabled orig, CharacterBody self)
		{
			if (!Object.op_Implicit((Object)(object)self) || !IsSoulEnemy(self))
			{
				orig.Invoke(self);
			}
		}

		private void OnCharacterDeathGlobal(orig_OnCharacterDeath orig, GlobalEventManager self, DamageReport damageReport)
		{
			orig.Invoke(self, damageReport);
			if (!IsEnabled.Value || !NetworkServer.active || damageReport == null)
			{
				return;
			}
			try
			{
				TrySpawnSoulEnemy(damageReport);
			}
			catch (Exception arg)
			{
				InstanceLogger.LogError((object)$"[RevampMySoul] Error in TrySpawnSoulEnemy: {arg}");
			}
		}

		private void TrySpawnSoulEnemy(DamageReport damageReport)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Invalid comparison between Unknown and I4
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			if (RequireArtifactOfSoul.Value && (!Object.op_Implicit((Object)(object)RunArtifactManager.instance) || !RunArtifactManager.instance.IsArtifactEnabled(Artifacts.wispOnDeath)))
			{
				return;
			}
			CharacterBody victimBody = damageReport.victimBody;
			CharacterMaster victimMaster = damageReport.victimMaster;
			if (!Object.op_Implicit((Object)(object)victimBody) || !Object.op_Implicit((Object)(object)victimMaster) || ((int)damageReport.victimTeamIndex != 2 && (!Object.op_Implicit((Object)(object)victimBody.teamComponent) || (int)victimBody.teamComponent.teamIndex != 2)))
			{
				return;
			}
			if ((Object)(object)((Component)victimMaster).GetComponent<SoulMarker>() != (Object)null || (Object.op_Implicit((Object)(object)victimBody) && (Object)(object)((Component)victimBody).GetComponent<SoulMarker>() != (Object)null))
			{
				if (EnableDebugLogging.Value)
				{
					InstanceLogger.LogInfo((object)("[RevampMySoul] Skipping soul spawn for " + ((Object)victimBody).name + " (already a soul)."));
				}
				return;
			}
			GameObject bodyPrefab = BodyCatalog.FindBodyPrefab(victimBody);
			if (!Object.op_Implicit((Object)(object)bodyPrefab))
			{
				return;
			}
			CharacterMaster val = MasterCatalog.allAiMasters.FirstOrDefault((Func<CharacterMaster, bool>)((CharacterMaster m) => Object.op_Implicit((Object)(object)m) && (Object)(object)m.bodyPrefab == (Object)(object)bodyPrefab));
			if (!Object.op_Implicit((Object)(object)val))
			{
				if (EnableDebugLogging.Value)
				{
					InstanceLogger.LogWarning((object)("[RevampMySoul] Could not find AI master prefab for body " + ((Object)bodyPrefab).name + "."));
				}
				return;
			}
			Vector3 footPosition = victimBody.footPosition;
			CharacterDirection component = ((Component)victimBody).GetComponent<CharacterDirection>();
			Quaternion val2 = (Object.op_Implicit((Object)(object)component) ? Quaternion.Euler(0f, component.yaw, 0f) : ((Component)victimBody).transform.rotation);
			EquipmentState victimEquipment = (((Object)(object)victimMaster.inventory != (Object)null) ? victimMaster.inventory.currentEquipmentState : EquipmentState.empty);
			int victimDoppelgangerCount = (((Object)(object)victimMaster.inventory != (Object)null) ? victimMaster.inventory.GetItemCountEffective(Items.InvadingDoppelganger) : 0);
			CharacterMaster val3 = new MasterSummon
			{
				masterPrefab = ((Component)val).gameObject,
				position = footPosition,
				rotation = val2,
				teamIndexOverride = (TeamIndex)2,
				ignoreTeamMemberLimit = true,
				useAmbientLevel = true,
				summonerBodyObject = null,
				inventoryToCopy = null,
				preSpawnSetupCallback = delegate(CharacterMaster soulMaster)
				{
					//IL_0080: Unknown result type (might be due to invalid IL or missing references)
					//IL_0086: Invalid comparison between Unknown and I4
					//IL_008f: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
					if (Object.op_Implicit((Object)(object)soulMaster) && Object.op_Implicit((Object)(object)soulMaster.inventory))
					{
						if (victimDoppelgangerCount > 0)
						{
							soulMaster.inventory.GiveItemPermanent(Items.InvadingDoppelganger, victimDoppelgangerCount);
							if (EnableDebugLogging.Value)
							{
								InstanceLogger.LogInfo((object)("[RevampMySoul] Transferred Doppelganger item to soul " + ((Object)soulMaster).name));
							}
						}
						else
						{
							soulMaster.inventory.GiveItemPermanent(Items.Ghost, 1);
						}
						if (TransferEliteAffixes.Value && (int)victimEquipment.equipmentIndex != -1)
						{
							soulMaster.inventory.SetEquipment(victimEquipment, 0u, 0u);
							if (EnableDebugLogging.Value)
							{
								EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(victimEquipment.equipmentIndex);
								InstanceLogger.LogInfo((object)("[RevampMySoul] Transferred elite essence '" + ((equipmentDef != null) ? ((Object)equipmentDef).name : null) + "' to soul " + ((Object)soulMaster).name));
							}
						}
						if (GrantEvolutionItems.Value && Object.op_Implicit((Object)(object)RunArtifactManager.instance) && RunArtifactManager.instance.IsArtifactEnabled(Artifacts.MonsterTeamGainsItems))
						{
							Inventory monsterTeamInventory = MonsterTeamInventory;
							if ((Object)(object)monsterTeamInventory != (Object)null)
							{
								soulMaster.inventory.AddItemsFrom(monsterTeamInventory);
								if (EnableDebugLogging.Value)
								{
									InstanceLogger.LogInfo((object)("[RevampMySoul] Granted Evolution items to soul " + ((Object)soulMaster).name));
								}
							}
						}
						if (DamageBoostPercentage.Value > 0)
						{
							int num = DamageBoostPercentage.Value / 10;
							if (num > 0)
							{
								soulMaster.inventory.GiveItemPermanent(Items.BoostDamage, num);
							}
						}
					}
				}
			}.Perform();
			if (Object.op_Implicit((Object)(object)val3))
			{
				((Component)val3).gameObject.AddComponent<SoulMarker>();
				((Component)val3).gameObject.AddComponent<SoulLifetimeTimer>().lifeTime = SoulLifetimeSeconds.Value;
				ApplySpawnAttributes(val3, footPosition, val2);
				if (EnableDebugLogging.Value)
				{
					InstanceLogger.LogInfo((object)$"[RevampMySoul] Successfully spawned soul enemy {((Object)val3).name} for defeated {((Object)victimBody).name} (Lifespan: {SoulLifetimeSeconds.Value}s, Invulnerability: {InvulnerabilityDuration.Value}s, XP: {SoulExpReward.Value}).");
				}
			}
		}

		private void ApplySpawnAttributes(CharacterMaster soulMaster, Vector3 spawnPos, Quaternion spawnRot)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if (PlayDioSpawnEffect.Value && Object.op_Implicit((Object)(object)HippoRezEffectPrefab))
			{
				EffectManager.SpawnEffect(HippoRezEffectPrefab, new EffectData
				{
					origin = spawnPos,
					rotation = spawnRot
				}, true);
			}
			float duration = InvulnerabilityDuration.Value;
			uint expReward = (uint)Math.Max(0, SoulExpReward.Value);
			CharacterBody body = soulMaster.GetBody();
			if (Object.op_Implicit((Object)(object)body))
			{
				ConfigureBodyRewards(body, expReward);
				GrantInvulnerabilityBuff(body, duration);
			}
			soulMaster.onBodyStart += delegate(CharacterBody newBody)
			{
				if (Object.op_Implicit((Object)(object)newBody))
				{
					ConfigureBodyRewards(newBody, expReward);
					GrantInvulnerabilityBuff(newBody, duration);
				}
			};
		}

		private static void ConfigureBodyRewards(CharacterBody body, uint expReward)
		{
			if (Object.op_Implicit((Object)(object)body))
			{
				DeathRewards val = ((Component)body).GetComponent<DeathRewards>();
				if (!Object.op_Implicit((Object)(object)val))
				{
					val = ((Component)body).gameObject.AddComponent<DeathRewards>();
				}
				val.expReward = expReward;
				if (val.spawnValue <= 0)
				{
					val.spawnValue = 1;
				}
			}
		}

		private static void GrantInvulnerabilityBuff(CharacterBody body, float duration)
		{
			if (Object.op_Implicit((Object)(object)body) && duration > 0f)
			{
				body.AddTimedBuff(Buffs.Immune, duration);
				if (EnableDebugLogging.Value)
				{
					InstanceLogger.LogInfo((object)$"[RevampMySoul] Applied {duration}s Dio's Best Friend (Immune) buff to {((Object)body).name}");
				}
			}
		}
	}
	public class SoulMarker : MonoBehaviour
	{
	}
	public class SoulFireEffectController : MonoBehaviour
	{
		private CharacterBody _body;

		private BurnEffectController _burnController;

		private void Start()
		{
			_body = ((Component)this).GetComponent<CharacterBody>();
			if (!Object.op_Implicit((Object)(object)_body))
			{
				return;
			}
			ModelLocator modelLocator = _body.modelLocator;
			Transform val = (Object.op_Implicit((Object)(object)modelLocator) ? modelLocator.modelTransform : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				SetupBurnEffect(((Component)val).gameObject);
			}
			else
			{
				if (!Object.op_Implicit((Object)(object)modelLocator))
				{
					return;
				}
				modelLocator.onModelChanged += delegate(Transform newModelTransform)
				{
					if (Object.op_Implicit((Object)(object)newModelTransform))
					{
						SetupBurnEffect(((Component)newModelTransform).gameObject);
					}
				};
			}
		}

		private void SetupBurnEffect(GameObject modelObject)
		{
			if (!Object.op_Implicit((Object)(object)_burnController) && Object.op_Implicit((Object)(object)modelObject))
			{
				_burnController = ((Component)this).gameObject.AddComponent<BurnEffectController>();
				_burnController.target = modelObject;
				_burnController.effectType = BurnEffectController.helfireEffect;
			}
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)_burnController))
			{
				Object.Destroy((Object)(object)_burnController);
				_burnController = null;
			}
		}
	}
	public static class RiskOfOptionsIntegration
	{
		public const string GUID = "com.rune580.riskofoptions";

		public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		public static void Init(ConfigEntry<bool> isEnabled, ConfigEntry<bool> requireArtifactOfSoul, ConfigEntry<bool> enableWispSoulFire, ConfigEntry<float> soulLifetimeSeconds, ConfigEntry<float> invulnerabilityDuration, ConfigEntry<bool> grantEvolutionItems, ConfigEntry<bool> transferEliteAffixes, ConfigEntry<int> soulExpReward, ConfigEntry<int> damageBoostPercentage, ConfigEntry<bool> enableDebugLogging)
		{
			if (!IsLoaded)
			{
				return;
			}
			try
			{
				InitInternal(isEnabled, requireArtifactOfSoul, enableWispSoulFire, soulLifetimeSeconds, invulnerabilityDuration, grantEvolutionItems, transferEliteAffixes, soulExpReward, damageBoostPercentage, enableDebugLogging);
			}
			catch (Exception ex)
			{
				ManualLogSource instanceLogger = Plugin.InstanceLogger;
				if (instanceLogger != null)
				{
					instanceLogger.LogWarning((object)("RiskOfOptions integration failed to initialize: " + ex.Message));
				}
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void InitInternal(ConfigEntry<bool> isEnabled, ConfigEntry<bool> requireArtifactOfSoul, ConfigEntry<bool> enableWispSoulFire, ConfigEntry<float> soulLifetimeSeconds, ConfigEntry<float> invulnerabilityDuration, ConfigEntry<bool> grantEvolutionItems, ConfigEntry<bool> transferEliteAffixes, ConfigEntry<int> soulExpReward, ConfigEntry<int> damageBoostPercentage, ConfigEntry<bool> enableDebugLogging)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Spawns an exact soul clone upon death with Happiest Mask ghost shader, Dio's Best Friend invulnerability, Elite essence, Evolution items, XP rewards, and a 30s lifetime.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(isEnabled));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(requireArtifactOfSoul));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(enableWispSoulFire));
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(soulLifetimeSeconds, new StepSliderConfig
			{
				min = 5f,
				max = 120f,
				increment = 5f,
				FormatString = "{0:0}s"
			}));
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(invulnerabilityDuration, new StepSliderConfig
			{
				min = 0f,
				max = 5f,
				increment = 0.25f,
				FormatString = "{0:0.00}s"
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(grantEvolutionItems));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(transferEliteAffixes));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(soulExpReward, new IntSliderConfig
			{
				min = 0,
				max = 50,
				formatString = "{0} XP"
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(damageBoostPercentage, new IntSliderConfig
			{
				min = 0,
				max = 300,
				formatString = "+{0}%"
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(enableDebugLogging));
		}
	}
	public class SoulLifetimeTimer : MonoBehaviour
	{
		public float lifeTime = 30f;

		public float timer;

		public bool hasDied;

		private CharacterMaster _characterMaster;

		private void Awake()
		{
			_characterMaster = ((Component)this).GetComponent<CharacterMaster>();
		}

		private void FixedUpdate()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || hasDied)
			{
				return;
			}
			timer += Time.fixedDeltaTime;
			if (!(timer >= lifeTime))
			{
				return;
			}
			hasDied = true;
			if (Plugin.EnableDebugLogging.Value)
			{
				ManualLogSource instanceLogger = Plugin.InstanceLogger;
				if (instanceLogger != null)
				{
					instanceLogger.LogInfo((object)$"[SoulLifetimeTimer] Soul lifespan ({lifeTime}s) expired for {((Object)this).name}. Triggering suicide.");
				}
			}
			CharacterBody val = (Object.op_Implicit((Object)(object)_characterMaster) ? _characterMaster.GetBody() : null);
			if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.healthComponent) && val.healthComponent.alive)
			{
				val.healthComponent.Suicide((GameObject)null, (GameObject)null, DamageTypeCombo.op_Implicit((DamageType)0));
			}
			else if (Object.op_Implicit((Object)(object)_characterMaster) && !_characterMaster.IsDeadAndOutOfLivesServer())
			{
				_characterMaster.TrueKill();
			}
		}
	}
}