using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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.Logging; using Microsoft.CodeAnalysis; using On.RoR2; using R2API; 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("ArtifactOfPandemonium")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ec019835087758f470ad70124cb9bb23cd073969")] [assembly: AssemblyProduct("ArtifactOfPandemonium")] [assembly: AssemblyTitle("ArtifactOfPandemonium")] [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 ArtifactOfPandemonium { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("AuthorName.ArtifactOfPandemonium", "ArtifactOfPandemonium", "1.1.0")] public class ArtifactOfPandemoniumPlugin : BaseUnityPlugin { private enum BlessingBuff { MoveSpeed, AttackSpeed, Money, Credits } public const string PluginGUID = "AuthorName.ArtifactOfPandemonium"; public const string PluginAuthor = "AuthorName"; public const string PluginName = "ArtifactOfPandemonium"; public const string PluginVersion = "1.1.0"; private const int MinimumOtherArtifacts = 2; private const int GuaranteedEnableCount = 2; private const float InitialEnableChance = 0.35f; private const float TruePandemoniumFixedTime = 99999f; private static int lastRolledStage = -1; private static bool stageAllUnlocked; private static HashSet activeStageBlessings = new HashSet(); private static float stageMoveSpeedMultiplier = 1f; private static float stageAttackSpeedMultiplier = 1f; private static float stageMoneyMultiplier = 1f; private static float stageCreditMultiplier = 1f; private static ArtifactDef artifactDef; private static BuffDef blessingBuffDef; private static readonly string[] BlessingHeaders = new string[5] { "Petrichor V's Blessing stirs on this stage...", "The world reshapes itself around the Pandemonium...", "Ancient forces align to your benefit...", "The planet tilts in your favor...", "Petrichor V whispers its secrets to you..." }; private static readonly string[] BlessingFullHeaders = new string[4] { "Every artifact resonates. Petrichor V's Blessing reaches its peak...", "The planet bows to your collection. Full power flows through you...", "Nothing is locked from you. The Pandemonium is complete...", "Petrichor V yields everything. The Blessing is unshackled..." }; public void Awake() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown Log.Init(((BaseUnityPlugin)this).Logger); artifactDef = ScriptableObject.CreateInstance(); artifactDef.cachedName = "ARTIFACT_PANDEMONIUM"; artifactDef.nameToken = "ARTIFACT_PANDEMONIUM_NAME"; artifactDef.descriptionToken = "ARTIFACT_PANDEMONIUM_DESC"; LanguageAPI.Add("ARTIFACT_PANDEMONIUM_NAME", "Artifact of Pandemonium"); LanguageAPI.Add("ARTIFACT_PANDEMONIUM_DESC", "Randomly enables other unlocked artifacts and grants Petrichor V's Blessing."); artifactDef.smallIconSelectedSprite = LoadSprite("ArtifactOfPandemonium.Resources.icon_selected.png"); artifactDef.smallIconDeselectedSprite = LoadSprite("ArtifactOfPandemonium.Resources.icon_deselected.png"); ContentAddition.AddArtifactDef(artifactDef); blessingBuffDef = ScriptableObject.CreateInstance(); ((Object)blessingBuffDef).name = "PETRICHOR_V_BLESSING"; blessingBuffDef.buffColor = new Color(0.4f, 0.75f, 1f); blessingBuffDef.canStack = false; blessingBuffDef.isDebuff = false; blessingBuffDef.isHidden = false; blessingBuffDef.iconSprite = LoadSprite("ArtifactOfPandemonium.Resources.icon_selected.png"); ContentAddition.AddBuffDef(blessingBuffDef); Run.onRunStartGlobal += OnRunStart; Stage.onServerStageBegin += OnServerStageBegin; DirectorAPI.StageSettingsActions += OnStageSettings; CharacterBody.onBodyStartGlobal += OnBodyStartGlobal; CharacterBody.onBodyDestroyGlobal += OnBodyDestroyGlobal; CharacterMaster.GiveMoney += new hook_GiveMoney(OnGiveMoney); Log.Info("ArtifactOfPandemonium loaded."); } private static void EnsureStageBlessingsRolled() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown if ((Object)(object)Run.instance == (Object)null) { return; } int stageClearCount = Run.instance.stageClearCount; if (stageClearCount != lastRolledStage) { lastRolledStage = stageClearCount; LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); UserProfile profile = ((firstLocalUser != null) ? firstLocalUser.userProfile : null); List list = ArtifactCatalog.artifactDefs.Where((ArtifactDef a) => (Object)(object)a != (Object)(object)artifactDef && (Object)(object)a != (Object)(object)Artifacts.Sacrifice).ToList(); int count = list.Count; int num = list.Count((ArtifactDef a) => IsUnlocked(a, profile)); float num2 = ((count > 0) ? Mathf.Clamp01((float)num / (float)count) : 0f); stageAllUnlocked = count > 0 && num >= count; Xoroshiro128Plus val = new Xoroshiro128Plus(Run.instance.seed ^ (ulong)(stageClearCount * 6364136223846793005L + 1442695040888963407L)); List list2 = new List { BlessingBuff.MoveSpeed, BlessingBuff.AttackSpeed, BlessingBuff.Money, BlessingBuff.Credits }; list2.RemoveAt(val.RangeInt(0, list2.Count)); activeStageBlessings = new HashSet(list2); stageMoveSpeedMultiplier = (activeStageBlessings.Contains(BlessingBuff.MoveSpeed) ? val.RangeFloat(Mathf.Lerp(1.05f, 1.15f, num2), Mathf.Lerp(1.15f, 1.4f, num2)) : 1f); stageAttackSpeedMultiplier = (activeStageBlessings.Contains(BlessingBuff.AttackSpeed) ? val.RangeFloat(Mathf.Lerp(1.05f, 1.15f, num2), Mathf.Lerp(1.15f, 1.4f, num2)) : 1f); stageMoneyMultiplier = (activeStageBlessings.Contains(BlessingBuff.Money) ? val.RangeFloat(Mathf.Lerp(1.05f, 1.1f, num2), Mathf.Lerp(1.15f, 1.3f, num2)) : 1f); stageCreditMultiplier = (activeStageBlessings.Contains(BlessingBuff.Credits) ? val.RangeFloat(Mathf.Lerp(1.1f, 1.25f, num2), Mathf.Lerp(1.25f, 1.6f, num2)) : 1f); } } private static void OnServerStageBegin(Stage stage) { if (IsBlessingActive()) { EnsureStageBlessingsRolled(); string[] array = (stageAllUnlocked ? BlessingFullHeaders : BlessingHeaders); int num = (int)((Run.instance.seed ^ (ulong)Run.instance.stageClearCount) % (ulong)array.Length); Chat.AddMessage("" + array[num] + ""); List list = new List(); if (activeStageBlessings.Contains(BlessingBuff.MoveSpeed)) { list.Add("▲ Speed " + FmtPct(stageMoveSpeedMultiplier) + ""); } if (activeStageBlessings.Contains(BlessingBuff.AttackSpeed)) { list.Add("▲ Atk Spd " + FmtPct(stageAttackSpeedMultiplier) + ""); } if (activeStageBlessings.Contains(BlessingBuff.Money)) { list.Add("▲ Gold " + FmtPct(stageMoneyMultiplier) + ""); } if (activeStageBlessings.Contains(BlessingBuff.Credits)) { list.Add("▲ Chests " + FmtPct(stageCreditMultiplier) + ""); } Chat.AddMessage(string.Join(" ", list)); } } private static string FmtPct(float multiplier) { return $"+{Mathf.RoundToInt((multiplier - 1f) * 100f)}%"; } private void OnRunStart(Run run) { lastRolledStage = -1; stageAllUnlocked = false; if (NetworkServer.active && IsBlessingActive()) { RunArtifactManager.instance.SetArtifactEnabledServer(Artifacts.Sacrifice, false); LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); UserProfile profile = ((firstLocalUser != null) ? firstLocalUser.userProfile : null); List list = ArtifactCatalog.artifactDefs.Where((ArtifactDef a) => (Object)(object)a != (Object)(object)artifactDef && (Object)(object)a != (Object)(object)Artifacts.Sacrifice && IsUnlocked(a, profile)).ToList(); if (list.Count < 2) { UnleashTruePandemonium(run); } else { RandomizeArtifacts(list); } } } private static bool IsUnlocked(ArtifactDef artifact, UserProfile profile) { if ((Object)(object)artifact.unlockableDef == (Object)null) { return true; } if (profile != null) { return profile.HasUnlockable(artifact.unlockableDef); } return false; } private void RandomizeArtifacts(List artifacts) { for (int num = artifacts.Count - 1; num > 0; num--) { int num2 = Random.Range(0, num + 1); int index = num; int index2 = num2; ArtifactDef value = artifacts[num2]; ArtifactDef value2 = artifacts[num]; artifacts[index] = value; artifacts[index2] = value2; } int num3 = Mathf.Min(2, artifacts.Count); for (int i = 0; i < num3; i++) { RunArtifactManager.instance.SetArtifactEnabledServer(artifacts[i], true); } float num4 = 0.35f; for (int j = num3; j < artifacts.Count; j++) { bool flag = Random.value < num4; RunArtifactManager.instance.SetArtifactEnabledServer(artifacts[j], flag); if (flag) { num4 *= 0.5f; } } Log.Info($"Pandemonium: randomized {artifacts.Count} other artifacts."); foreach (ArtifactDef artifact in artifacts) { bool flag2 = RunArtifactManager.instance.IsArtifactEnabled(artifact); Log.Info(" " + artifact.cachedName + ": " + (flag2 ? "ENABLED" : "disabled")); } } private void UnleashTruePandemonium(Run run) { Chat.AddMessage("Too few artifacts are unlocked for Pandemonium to choose from. True pandemonium will be unleashed..."); Log.Warning("Pandemonium: fewer than 2 other unlocked artifacts found. Forcing max enemy level."); run.NetworkfixedTime = 99999f; } private void OnStageSettings(StageSettings settings, StageInfo stageInfo) { if (IsBlessingActive()) { EnsureStageBlessingsRolled(); if (activeStageBlessings.Contains(BlessingBuff.Credits)) { settings.SceneDirectorInteractableCredits = Mathf.RoundToInt((float)settings.SceneDirectorInteractableCredits * stageCreditMultiplier); } } } private static bool IsBlessingActive() { if ((Object)(object)Run.instance != (Object)null && (Object)(object)RunArtifactManager.instance != (Object)null) { return RunArtifactManager.instance.IsArtifactEnabled(artifactDef); } return false; } private void OnBodyStartGlobal(CharacterBody body) { if (IsBlessingActive() && body.isPlayerControlled) { EnsureStageBlessingsRolled(); body.onRecalculateStats += OnRecalculateStats; body.AddBuff(blessingBuffDef); } } private void OnBodyDestroyGlobal(CharacterBody body) { body.onRecalculateStats -= OnRecalculateStats; } private void OnRecalculateStats(CharacterBody body) { if (body.HasBuff(blessingBuffDef)) { EnsureStageBlessingsRolled(); if (activeStageBlessings.Contains(BlessingBuff.MoveSpeed)) { body.moveSpeed *= stageMoveSpeedMultiplier; } if (activeStageBlessings.Contains(BlessingBuff.AttackSpeed)) { body.attackSpeed *= stageAttackSpeedMultiplier; } } } private void OnGiveMoney(orig_GiveMoney orig, CharacterMaster self, uint amount) { if ((Object)(object)self.playerCharacterMasterController != (Object)null && IsBlessingActive()) { EnsureStageBlessingsRolled(); if (activeStageBlessings.Contains(BlessingBuff.Money)) { amount = (uint)Mathf.RoundToInt((float)amount * stageMoneyMultiplier); } } orig.Invoke(self, amount); } private static Sprite LoadSprite(string resourceName) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName); byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(256, 256); ImageConversion.LoadImage(val, array); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } }