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.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using On.RoR2; using RoR2; using UnityEngine; using UnityEngine.Networking; 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("BossMutations")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BossMutations")] [assembly: AssemblyTitle("BossMutations")] [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 BossMutations { [BepInPlugin("dileppy.bossmutations", "BossMutations", "1.0.0")] public class BossMutationsPlugin : BaseUnityPlugin { public enum BossMutationType { None, Colossal, Frenzied, Shielded, Volatile, Splitting } public class BossMutationMarker : MonoBehaviour { public BossMutationType type; public float rewardMult = 1f; public bool burst75; public bool burst50; public bool burst25; public bool split66; public bool split33; public float nextShieldTime; } public class SplitChildMarker : MonoBehaviour { } private class SizeMarker : MonoBehaviour { public Vector3 baseScale; } public const string PluginGUID = "dileppy.bossmutations"; public const string PluginName = "BossMutations"; public const string PluginVersion = "1.0.0"; public static ConfigEntry BossMutationChance; public static ConfigEntry ChancePerLoop; public static ConfigEntry EnableColossal; public static ConfigEntry EnableFrenzied; public static ConfigEntry EnableShielded; public static ConfigEntry EnableVolatile; public static ConfigEntry EnableSplitting; public static ConfigEntry AnnounceMutation; public static ConfigEntry SplitCount; public static ConfigEntry ShieldPulseInterval; public static ConfigEntry ShieldPulseFraction; public static ConfigEntry VolatileBurstDamage; public static ConfigEntry VolatileBurstRadius; public static ConfigEntry DebugLogging; private static readonly Random rng = new Random(); private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Expected O, but got Unknown BossMutationChance = ((BaseUnityPlugin)this).Config.Bind("General", "BossMutationChance", 25f, new ConfigDescription("Percent chance a boss spawns mutated.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 100f), Array.Empty())); ChancePerLoop = ((BaseUnityPlugin)this).Config.Bind("General", "ChancePerLoop", 10f, new ConfigDescription("Percent added to the chance per completed loop.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), Array.Empty())); AnnounceMutation = ((BaseUnityPlugin)this).Config.Bind("General", "AnnounceMutation", true, "Post a chat message naming the boss mutation when one spawns."); EnableColossal = ((BaseUnityPlugin)this).Config.Bind("Mutations", "EnableColossal", true, "180% size, double HP, +30% damage, slower attacks. A monument."); EnableFrenzied = ((BaseUnityPlugin)this).Config.Bind("Mutations", "EnableFrenzied", true, "+40% speed and attack speed, -25% HP. A blur."); EnableShielded = ((BaseUnityPlugin)this).Config.Bind("Mutations", "EnableShielded", true, "Periodically gains a barrier. Burst it down in the windows."); EnableVolatile = ((BaseUnityPlugin)this).Config.Bind("Mutations", "EnableVolatile", true, "Explosion bursts at 75/50/25% health. Respect the space."); EnableSplitting = ((BaseUnityPlugin)this).Config.Bind("Mutations", "EnableSplitting", true, "Spawns smaller copies of itself at 66% and 33% health."); SplitCount = ((BaseUnityPlugin)this).Config.Bind("Mutations", "SplitCount", 2, new ConfigDescription("How many smaller copies each split spawns.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 4), Array.Empty())); ShieldPulseInterval = ((BaseUnityPlugin)this).Config.Bind("Mutations", "ShieldPulseInterval", 12f, new ConfigDescription("Seconds between Shielded barrier pulses.", (AcceptableValueBase)(object)new AcceptableValueRange(4f, 60f), Array.Empty())); ShieldPulseFraction = ((BaseUnityPlugin)this).Config.Bind("Mutations", "ShieldPulseFraction", 0.25f, new ConfigDescription("Barrier gained per pulse as a fraction of max HP.", (AcceptableValueBase)(object)new AcceptableValueRange(0.05f, 1f), Array.Empty())); VolatileBurstDamage = ((BaseUnityPlugin)this).Config.Bind("Mutations", "VolatileBurstDamage", 10f, new ConfigDescription("Volatile burst damage as a multiple of the boss's base damage.", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 50f), Array.Empty())); VolatileBurstRadius = ((BaseUnityPlugin)this).Config.Bind("Mutations", "VolatileBurstRadius", 18f, new ConfigDescription("Volatile burst radius in meters.", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 50f), Array.Empty())); DebugLogging = ((BaseUnityPlugin)this).Config.Bind("Advanced", "DebugLogging", false, "Log rolls and threshold triggers."); CharacterBody.Start += new hook_Start(CharacterBody_Start); CharacterBody.RecalculateStats += new hook_RecalculateStats(CharacterBody_RecalculateStats); DeathRewards.OnKilledServer += new hook_OnKilledServer(DeathRewards_OnKilledServer); ((BaseUnityPlugin)this).Logger.LogInfo((object)"BossMutations v1.0.0 loaded. Part of The Petrichor Protocol."); } 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 CharacterBody.Start -= new hook_Start(CharacterBody_Start); CharacterBody.RecalculateStats -= new hook_RecalculateStats(CharacterBody_RecalculateStats); DeathRewards.OnKilledServer -= new hook_OnKilledServer(DeathRewards_OnKilledServer); } 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(); if (!Object.op_Implicit((Object)(object)sizeMarker)) { sizeMarker = go.AddComponent(); sizeMarker.baseScale = go.transform.localScale; } go.transform.localScale = sizeMarker.baseScale * factor; } } private static void ApplyModelScale(CharacterBody body, float factor) { ModelLocator modelLocator = body.modelLocator; if (Object.op_Implicit((Object)(object)modelLocator) && Object.op_Implicit((Object)(object)modelLocator.modelTransform)) { ApplyAbsoluteScale(((Component)modelLocator.modelTransform).gameObject, factor); } } private void CharacterBody_Start(orig_Start orig, CharacterBody self) { orig.Invoke(self); if (!NetworkServer.active || !self.isBoss || Object.op_Implicit((Object)(object)((Component)self).GetComponent())) { return; } if (Object.op_Implicit((Object)(object)self.master) && Object.op_Implicit((Object)(object)((Component)self.master).GetComponent())) { ApplyModelScale(self, 0.5f); BossMutationMarker bossMutationMarker = ((Component)self).gameObject.AddComponent(); bossMutationMarker.type = BossMutationType.None; bossMutationMarker.rewardMult = 0.25f; self.RecalculateStats(); return; } try { int num = (Object.op_Implicit((Object)(object)Run.instance) ? Run.instance.loopClearCount : 0); float num2 = BossMutationChance.Value + ChancePerLoop.Value * (float)num; if (rng.NextDouble() * 100.0 > (double)num2) { return; } List list = new List(); if (EnableColossal.Value) { list.Add(BossMutationType.Colossal); } if (EnableFrenzied.Value) { list.Add(BossMutationType.Frenzied); } if (EnableShielded.Value) { list.Add(BossMutationType.Shielded); } if (EnableVolatile.Value) { list.Add(BossMutationType.Volatile); } if (EnableSplitting.Value) { list.Add(BossMutationType.Splitting); } if (list.Count != 0) { BossMutationType bossMutationType = list[rng.Next(list.Count)]; BossMutationMarker bossMutationMarker2 = ((Component)self).gameObject.AddComponent(); bossMutationMarker2.type = bossMutationType; switch (bossMutationType) { case BossMutationType.Colossal: ApplyModelScale(self, 1.8f); bossMutationMarker2.rewardMult = 2f; break; case BossMutationType.Frenzied: ApplyModelScale(self, 0.95f); bossMutationMarker2.rewardMult = 1.6f; break; case BossMutationType.Shielded: bossMutationMarker2.rewardMult = 1.5f; bossMutationMarker2.nextShieldTime = Time.time + ShieldPulseInterval.Value; break; case BossMutationType.Volatile: ApplyModelScale(self, 1.1f); bossMutationMarker2.rewardMult = 1.6f; break; case BossMutationType.Splitting: ApplyModelScale(self, 1.15f); bossMutationMarker2.rewardMult = 1.8f; break; } ((Component)self).gameObject.AddComponent().Init(self, bossMutationMarker2, ((BaseUnityPlugin)this).Logger); self.RecalculateStats(); if (AnnounceMutation.Value) { Chat.AddMessage($"A {bossMutationType} {self.GetDisplayName()} emerges!"); } if (DebugLogging.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0}: {1} rolled {2} ({3:F0}%)", "BossMutations", self.GetDisplayName(), bossMutationType, num2)); } } } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("{0}: boss roll failed: {1}", "BossMutations", arg)); } } private void CharacterBody_RecalculateStats(orig_RecalculateStats orig, CharacterBody self) { orig.Invoke(self); BossMutationMarker bossMutationMarker = (Object.op_Implicit((Object)(object)self) ? ((Component)self).GetComponent() : null); if ((Object)(object)bossMutationMarker == (Object)null) { return; } if (Object.op_Implicit((Object)(object)self.master) && Object.op_Implicit((Object)(object)((Component)self.master).GetComponent())) { self.maxHealth *= 0.25f; self.damage *= 0.5f; return; } switch (bossMutationMarker.type) { case BossMutationType.Colossal: self.maxHealth *= 2f; self.damage *= 1.3f; self.attackSpeed *= 0.8f; self.moveSpeed *= 0.85f; break; case BossMutationType.Frenzied: self.maxHealth *= 0.75f; self.moveSpeed *= 1.4f; self.attackSpeed *= 1.4f; break; case BossMutationType.Splitting: self.maxHealth *= 0.85f; break; case BossMutationType.Shielded: case BossMutationType.Volatile: break; } } private void DeathRewards_OnKilledServer(orig_OnKilledServer orig, DeathRewards self, DamageReport damageReport) { BossMutationMarker bossMutationMarker = (Object.op_Implicit((Object)(object)damageReport?.victimBody) ? ((Component)damageReport.victimBody).GetComponent() : null); if ((Object)(object)bossMutationMarker != (Object)null && bossMutationMarker.rewardMult != 1f) { self.goldReward = (uint)((float)self.goldReward * bossMutationMarker.rewardMult); self.expReward = (uint)((float)self.expReward * bossMutationMarker.rewardMult); } orig.Invoke(self, damageReport); } } public class BossMutationWatcher : MonoBehaviour { private CharacterBody body; private BossMutationsPlugin.BossMutationMarker marker; private ManualLogSource log; public void Init(CharacterBody b, BossMutationsPlugin.BossMutationMarker m, ManualLogSource l) { body = b; marker = m; log = l; } private void FixedUpdate() { if (!NetworkServer.active || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.healthComponent) || !body.healthComponent.alive || (Object)(object)marker == (Object)null) { return; } float combinedHealthFraction = body.healthComponent.combinedHealthFraction; if (marker.type == BossMutationsPlugin.BossMutationType.Volatile) { if (!marker.burst75 && combinedHealthFraction <= 0.75f) { marker.burst75 = true; Burst(); } if (!marker.burst50 && combinedHealthFraction <= 0.5f) { marker.burst50 = true; Burst(); } if (!marker.burst25 && combinedHealthFraction <= 0.25f) { marker.burst25 = true; Burst(); } } else if (marker.type == BossMutationsPlugin.BossMutationType.Splitting) { if (!marker.split66 && combinedHealthFraction <= 0.66f) { marker.split66 = true; Split(); } if (!marker.split33 && combinedHealthFraction <= 0.33f) { marker.split33 = true; Split(); } } else if (marker.type == BossMutationsPlugin.BossMutationType.Shielded && Time.time >= marker.nextShieldTime) { marker.nextShieldTime = Time.time + BossMutationsPlugin.ShieldPulseInterval.Value; body.healthComponent.AddBarrier(body.maxHealth * BossMutationsPlugin.ShieldPulseFraction.Value); } } private void Burst() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0027: 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_004d: 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_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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown try { new BlastAttack { attacker = ((Component)body).gameObject, inflictor = ((Component)body).gameObject, teamIndex = (TeamIndex)((!Object.op_Implicit((Object)(object)body.teamComponent)) ? 2 : ((int)body.teamComponent.teamIndex)), baseDamage = body.baseDamage * BossMutationsPlugin.VolatileBurstDamage.Value, baseForce = 1200f, position = body.corePosition, radius = BossMutationsPlugin.VolatileBurstRadius.Value, falloffModel = (FalloffModel)1, attackerFiltering = (AttackerFiltering)2 }.Fire(); GameObject val = LegacyResourcesAPI.Load("Prefabs/Effects/OmniEffect/OmniExplosionVFX"); if (Object.op_Implicit((Object)(object)val)) { EffectManager.SpawnEffect(val, new EffectData { origin = body.corePosition, scale = BossMutationsPlugin.VolatileBurstRadius.Value }, true); } } catch (Exception arg) { log.LogError((object)$"BossMutations: burst failed: {arg}"); } } private void Split() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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) try { if (!Object.op_Implicit((Object)(object)body.master)) { return; } GameObject masterPrefab = MasterCatalog.GetMasterPrefab(body.master.masterIndex); if (!Object.op_Implicit((Object)(object)masterPrefab)) { return; } for (int i = 0; i < BossMutationsPlugin.SplitCount.Value; i++) { CharacterMaster val = new MasterSummon { masterPrefab = masterPrefab, position = body.corePosition + Random.insideUnitSphere * 4f, rotation = Quaternion.identity, teamIndexOverride = (TeamIndex)((!Object.op_Implicit((Object)(object)body.teamComponent)) ? 2 : ((int)body.teamComponent.teamIndex)), ignoreTeamMemberLimit = true }.Perform(); if (Object.op_Implicit((Object)(object)val)) { ((Component)val).gameObject.AddComponent(); } } } catch (Exception arg) { log.LogError((object)$"BossMutations: split failed: {arg}"); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "BossMutations"; public const string PLUGIN_NAME = "BossMutations"; public const string PLUGIN_VERSION = "1.0.0"; } }