Decompiled source of ShrunkenEnemies v1.0.0

ShrunkenEnemies.dll

Decompiled 12 hours ago
using System;
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.Bootstrap;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.Projectile;
using RoR2;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.SceneManagement;

[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("ShrunkenEnemies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShrunkenEnemies")]
[assembly: AssemblyTitle("ShrunkenEnemies")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ShrunkenEnemies
{
	[BepInPlugin("dileppy.shrunkenenemies", "ShrunkenEnemies", "1.0.0")]
	public class ShrunkenEnemiesPlugin : BaseUnityPlugin
	{
		public enum SizeTier
		{
			Small,
			ExtraSmall,
			ExtremelySmall
		}

		private struct TierValues
		{
			public float size;

			public float damage;

			public float health;

			public float move;

			public float rewardMult;

			public TierValues(float s, float d, float h, float m, float r)
			{
				size = s;
				damage = d;
				health = h;
				move = m;
				rewardMult = r;
			}
		}

		private class SizeMarker : MonoBehaviour
		{
			public Vector3 baseScale;
		}

		public const string PluginGUID = "dileppy.shrunkenenemies";

		public const string PluginName = "ShrunkenEnemies";

		public const string PluginVersion = "1.0.0";

		private const string RivalModGUID = "dileppy.enlargedenemies";

		private static readonly Dictionary<SizeTier, TierValues> Defaults = new Dictionary<SizeTier, TierValues>
		{
			{
				SizeTier.Small,
				new TierValues(0.7f, 0.8f, 0.8f, 1.15f, 0.85f)
			},
			{
				SizeTier.ExtraSmall,
				new TierValues(0.5f, 0.6f, 0.6f, 1.3f, 0.65f)
			},
			{
				SizeTier.ExtremelySmall,
				new TierValues(0.3f, 0.4f, 0.4f, 1.5f, 0.4f)
			}
		};

		public static ConfigEntry<SizeTier> Tier;

		public static ConfigEntry<bool> ScaleProjectiles;

		public static ConfigEntry<bool> AffectBosses;

		public static ConfigEntry<bool> ScaleRewards;

		public static ConfigEntry<bool> UseCustomValues;

		public static ConfigEntry<float> CustomSize;

		public static ConfigEntry<float> CustomDamage;

		public static ConfigEntry<float> CustomHealth;

		public static ConfigEntry<float> CustomMove;

		public static ConfigEntry<float> CustomReward;

		public static ConfigEntry<bool> DebugLogging;

		private void Awake()
		{
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Expected O, but got Unknown
			Tier = ((BaseUnityPlugin)this).Config.Bind<SizeTier>("General", "SizeTier", SizeTier.Small, "How shrunken the enemies are. Small=70%, ExtraSmall=50%, ExtremelySmall=30%. Smaller enemies are weaker and drop less, but move faster and are harder to hit.");
			ScaleProjectiles = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ScaleProjectiles", true, "Also shrink enemy projectiles to match their size.");
			AffectBosses = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AffectBosses", true, "Whether bosses and teleporter events are shrunk too. Disable for tiny trash mobs but full-size bosses.");
			ScaleRewards = ((BaseUnityPlugin)this).Config.Bind<bool>("Challenge", "ScaleRewards", true, "Small fry drop small rewards: -15% (Small), -35% (ExtraSmall), -60% (ExtremelySmall) gold and XP. Keeps easy mode from also being farm mode.");
			UseCustomValues = ((BaseUnityPlugin)this).Config.Bind<bool>("Custom", "UseCustomValues", false, "Ignore the tier presets and use the Custom* values below instead.");
			CustomSize = ((BaseUnityPlugin)this).Config.Bind<float>("Custom", "CustomSize", 0.5f, new ConfigDescription("Enemy size multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
			CustomDamage = ((BaseUnityPlugin)this).Config.Bind<float>("Custom", "CustomDamage", 0.6f, new ConfigDescription("Enemy damage multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
			CustomHealth = ((BaseUnityPlugin)this).Config.Bind<float>("Custom", "CustomHealth", 0.6f, new ConfigDescription("Enemy max HP multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>()));
			CustomMove = ((BaseUnityPlugin)this).Config.Bind<float>("Custom", "CustomMove", 1.3f, new ConfigDescription("Enemy move speed multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), Array.Empty<object>()));
			CustomReward = ((BaseUnityPlugin)this).Config.Bind<float>("Custom", "CustomReward", 0.65f, new ConfigDescription("Gold/XP drop multiplier", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), Array.Empty<object>()));
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "DebugLogging", false, "Log applied multipliers to the console for verification.");
			if (Chainloader.PluginInfos.ContainsKey("dileppy.enlargedenemies"))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"ShrunkenEnemies: EnlargedEnemies is also installed. Running both at once will produce unpredictable results. Use one at a time.");
			}
			CharacterBody.Start += new hook_Start(CharacterBody_Start);
			CharacterBody.RecalculateStats += new hook_RecalculateStats(CharacterBody_RecalculateStats);
			ProjectileController.Start += new hook_Start(ProjectileController_Start);
			DeathRewards.OnKilledServer += new hook_OnKilledServer(DeathRewards_OnKilledServer);
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded. Tier={2}", "ShrunkenEnemies", "1.0.0", Tier.Value));
		}

		private void OnDestroy()
		{
			//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
			CharacterBody.Start -= new hook_Start(CharacterBody_Start);
			CharacterBody.RecalculateStats -= new hook_RecalculateStats(CharacterBody_RecalculateStats);
			ProjectileController.Start -= new hook_Start(ProjectileController_Start);
			DeathRewards.OnKilledServer -= new hook_OnKilledServer(DeathRewards_OnKilledServer);
		}

		private TierValues Current()
		{
			if (UseCustomValues.Value)
			{
				return new TierValues(CustomSize.Value, CustomDamage.Value, CustomHealth.Value, CustomMove.Value, CustomReward.Value);
			}
			return Defaults[Tier.Value];
		}

		private static bool IsTargetEnemy(CharacterBody body)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.teamComponent))
			{
				return false;
			}
			TeamIndex teamIndex = body.teamComponent.teamIndex;
			if ((int)teamIndex != 2 && (int)teamIndex != 3 && (int)teamIndex != 4)
			{
				return false;
			}
			if (!AffectBosses.Value && body.isBoss)
			{
				return false;
			}
			return true;
		}

		private static void ApplyAbsoluteScale(GameObject go, float factor)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)go))
			{
				return;
			}
			Scene scene = go.scene;
			if (((Scene)(ref scene)).IsValid())
			{
				SizeMarker sizeMarker = go.GetComponent<SizeMarker>();
				if (!Object.op_Implicit((Object)(object)sizeMarker))
				{
					sizeMarker = go.AddComponent<SizeMarker>();
					sizeMarker.baseScale = go.transform.localScale;
				}
				go.transform.localScale = sizeMarker.baseScale * factor;
			}
		}

		private void CharacterBody_Start(orig_Start orig, CharacterBody self)
		{
			orig.Invoke(self);
			if (!IsTargetEnemy(self))
			{
				return;
			}
			try
			{
				ModelLocator modelLocator = self.modelLocator;
				if (Object.op_Implicit((Object)(object)modelLocator) && Object.op_Implicit((Object)(object)modelLocator.modelTransform))
				{
					ApplyAbsoluteScale(((Component)modelLocator.modelTransform).gameObject, Current().size);
					if (DebugLogging.Value)
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0}: scaled {1} to {2:P0}", "ShrunkenEnemies", self.GetDisplayName(), Current().size));
					}
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("{0}: model scale failed: {1}", "ShrunkenEnemies", arg));
			}
		}

		private void CharacterBody_RecalculateStats(orig_RecalculateStats orig, CharacterBody self)
		{
			orig.Invoke(self);
			if (IsTargetEnemy(self))
			{
				TierValues tierValues = Current();
				self.damage *= tierValues.damage;
				self.maxHealth *= tierValues.health;
				self.moveSpeed *= tierValues.move;
			}
		}

		private void ProjectileController_Start(orig_Start orig, ProjectileController self)
		{
			orig.Invoke(self);
			if (!ScaleProjectiles.Value || !Object.op_Implicit((Object)(object)self.owner))
			{
				return;
			}
			CharacterBody component = self.owner.GetComponent<CharacterBody>();
			if (!Object.op_Implicit((Object)(object)component) || !IsTargetEnemy(component))
			{
				return;
			}
			try
			{
				float size = Current().size;
				ApplyAbsoluteScale(((Component)self).gameObject, size);
				if (Object.op_Implicit((Object)(object)self.ghost))
				{
					ApplyAbsoluteScale(((Component)self.ghost).gameObject, size);
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("{0}: projectile scale failed: {1}", "ShrunkenEnemies", arg));
			}
		}

		private void DeathRewards_OnKilledServer(orig_OnKilledServer orig, DeathRewards self, DamageReport damageReport)
		{
			if (ScaleRewards.Value && !UseCustomValues.Value && (Object)(object)damageReport?.victimBody != (Object)null && IsTargetEnemy(damageReport.victimBody))
			{
				float rewardMult = Current().rewardMult;
				self.goldReward = (uint)((float)self.goldReward * rewardMult);
				self.expReward = (uint)((float)self.expReward * rewardMult);
			}
			else if (ScaleRewards.Value && UseCustomValues.Value && (Object)(object)damageReport?.victimBody != (Object)null && IsTargetEnemy(damageReport.victimBody))
			{
				self.goldReward = (uint)((float)self.goldReward * CustomReward.Value);
				self.expReward = (uint)((float)self.expReward * CustomReward.Value);
			}
			orig.Invoke(self, damageReport);
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ShrunkenEnemies";

		public const string PLUGIN_NAME = "ShrunkenEnemies";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}