Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Uncap player level v2.0.2
plugins/UncapPlayerLevel/UncapPlayerLevel.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Numerics; 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 Microsoft.CodeAnalysis; using On.RoR2; using On.RoR2.Items; using ProperSave; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Items; 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("UncapPlayerLevel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+fe14cb3162fc1415b7b32c843dc0cb8e92475b2e")] [assembly: AssemblyProduct("UncapPlayerLevel")] [assembly: AssemblyTitle("UncapPlayerLevel")] [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 UncapPlayerLevel { internal static class DebugKeys { public static void Update() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if (UncapPlayerLevel.debugKeys.Value) { KeyboardShortcut value = UncapPlayerLevel.spawnPrayerBeadsKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Spawn(Items.ExtraStatsOnLevelUp); } value = UncapPlayerLevel.spawnSolitudeKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Spawn(Items.OnLevelUpFreeUnlock); } value = UncapPlayerLevel.spawnBrittleCrownKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Spawn(Items.GoldOnHit); } } } private static void Spawn(ItemDef item) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)item) || !Object.op_Implicit((Object)(object)Run.instance)) { return; } if (!NetworkServer.active) { Log.Warning("The debug keys only work for the host"); return; } LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser(); CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null); if (Object.op_Implicit((Object)(object)val)) { Vector3 val2 = (Object.op_Implicit((Object)(object)val.inputBank) ? val.inputBank.aimDirection : val.transform.forward); val2.y = 0f; PickupDropletController.CreatePickupDroplet(new UniquePickup(PickupCatalog.FindPickupIndex(item.itemIndex)), val.corePosition, Vector3.up * 20f + ((Vector3)(ref val2)).normalized * 5f, false); Log.Info("Debug key pressed, spawned " + ((Object)item).name); } } } internal static class KillExperienceHooks { [CompilerGenerated] private static class <>O { public static hook_OnKilledServer <0>__OnKilledServer; public static hook_AwardExperience <1>__AwardExperience; } private const double EXPERIENCE_PER_LEVEL = 0.3; private const double VANILLA_LIMIT = 4290000000.0; private const double STUCK_LEVEL = 2147483648.0; private static BigInteger killExperience; public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__OnKilledServer; if (obj == null) { hook_OnKilledServer val = OnKilledServer; <>O.<0>__OnKilledServer = val; obj = (object)val; } DeathRewards.OnKilledServer += (hook_OnKilledServer)obj; object obj2 = <>O.<1>__AwardExperience; if (obj2 == null) { hook_AwardExperience val2 = AwardExperience; <>O.<1>__AwardExperience = val2; obj2 = (object)val2; } ExperienceManager.AwardExperience += (hook_AwardExperience)obj2; } private static void OnKilledServer(orig_OnKilledServer orig, DeathRewards self, DamageReport damageReport) { killExperience = GetExperience(self); try { orig.Invoke(self, damageReport); } finally { killExperience = BigInteger.Zero; } } private static BigInteger GetExperience(DeathRewards rewards) { CharacterBody characterBody = rewards.characterBody; Run instance = Run.instance; if (!Object.op_Implicit((Object)(object)characterBody) || !Object.op_Implicit((Object)(object)instance)) { return BigInteger.Zero; } double num = rewards.expReward; double num2 = (double)rewards.spawnValue * (double)instance.compensatedDifficultyCoefficient; if (num2 > 4294967295.0) { num = num2; } double num3 = num * (1.0 + (GetLevel(characterBody, instance) - 1.0) * 0.3); if (double.IsNaN(num3) || num3 <= 4290000000.0) { return BigInteger.Zero; } return new BigInteger(Math.Min(num3, double.MaxValue)); } private static double GetLevel(CharacterBody body, Run run) { double num = body.level; if (!(num >= 2147483648.0)) { return num; } return Math.Max(num, run.ambientLevel); } private static void AwardExperience(orig_AwardExperience orig, ExperienceManager self, Vector3 origin, CharacterBody body, ulong amount) { //IL_0037: 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_0067: Unknown result type (might be due to invalid IL or missing references) BigInteger bigInteger = killExperience; killExperience = BigInteger.Zero; if (bigInteger.IsZero || SuppressExperience.suppressExperience || !Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.master)) { orig.Invoke(self, origin, body, amount); return; } BigInteger bigInteger2 = BigInteger.Min(bigInteger, CharacterMaster.maxXPDisplay); orig.Invoke(self, origin, body, (ulong)bigInteger2); TeamManagerHooks.GiveExperience(body.master.teamIndex, bigInteger - bigInteger2); } } internal readonly struct LevelSettings { public const int GROWTH_SCALE = 1000; public readonly int InitialCost; public readonly uint MaxLevel; public readonly uint LevelsPerLevelUp; public readonly int Growth; public bool IsFlat => Growth == 1000; public LevelSettings(int initialCost, int maxLevel, int levelsPerLevelUp, float growthPercent) { InitialCost = Math.Max(1, initialCost); MaxLevel = (uint)Math.Max(1, maxLevel); LevelsPerLevelUp = (uint)Math.Max(1, levelsPerLevelUp); double num = Math.Round((double)growthPercent * 10.0); Growth = ((num > 1000.0) ? ((int)Math.Min(num, 2147483647.0)) : 1000); } } internal sealed class LevelProgress { private const int COST_FRACTION_BITS = 16; private const double MAX_COST_BITS = 16777216.0; private const int MAX_FIELD_BITS = 62; private const int BULK_LEVEL_UPS = 64; private const int BULK_MARGIN = 2; private const int BULK_MIN_COST_BITS = 20; private BigInteger scaledCost; private BigInteger cost; private BigInteger experience; private ulong pending; private ulong room; private int progressShift; private ulong progressCost; private ulong progressExperience; private int packShift; private ulong packCost; private ulong packExperience; public uint Level { get; private set; } public BigInteger Experience { get { if (pending != 0L) { return experience + pending; } return experience; } } public BigInteger NextLevelCost => cost; public LevelProgress(in LevelSettings settings) { Reset(in settings); } public void Reset(in LevelSettings settings) { Level = 1u; experience = BigInteger.Zero; pending = 0uL; SetScaledCost((BigInteger)settings.InitialCost << 16); Refresh(); } public void Restore(uint level, BigInteger experience, BigInteger nextLevelCost, in LevelSettings settings) { Level = Math.Max(1u, level); this.experience = BigInteger.Max(BigInteger.Zero, experience); pending = 0uL; SetScaledCost(BigInteger.Max(BigInteger.One, nextLevelCost) << 16); SettleLevelUps(in settings); } public void AddExperience(ulong amount, in LevelSettings settings) { if (Level >= settings.MaxLevel) { ClearAtCap(); return; } if (amount < room - pending) { pending += amount; return; } experience += (BigInteger)pending; experience += (BigInteger)amount; pending = 0uL; SettleLevelUps(in settings); } public void AddExperience(BigInteger amount, in LevelSettings settings) { if (Level >= settings.MaxLevel) { ClearAtCap(); return; } if (amount.Sign > 0 && amount.CompareTo(room - pending) < 0) { pending += (ulong)amount; return; } experience += (BigInteger)pending; if (amount.Sign > 0) { experience += amount; } pending = 0uL; SettleLevelUps(in settings); } public void SetLevel(uint level, in LevelSettings settings) { Level = Math.Min(Math.Max(1u, level), settings.MaxLevel); experience = BigInteger.Zero; pending = 0uL; ulong levelUps = (ulong)((long)Level - 1L + settings.LevelsPerLevelUp - 1) / (ulong)settings.LevelsPerLevelUp; SetScaledCost(ScaledCostAfter(levelUps, in settings)); Refresh(); } public void GetProgress(out ulong experience, out ulong nextLevelExperience) { nextLevelExperience = progressCost; experience = Math.Min(progressExperience + ShiftRight(pending, progressShift), progressCost); } public int Pack(out ulong experience, out ulong nextLevelCost) { ulong num = ((packShift >= 16) ? ShiftRight(pending, packShift - 16) : (pending << 16 - packShift)); nextLevelCost = packCost; experience = Math.Min(packExperience + num, packCost); return packShift; } public void Unpack(uint level, ulong experience, ulong nextLevelCost, int shift, in LevelSettings settings) { shift = Math.Max(0, shift); Level = Math.Max(1u, level); this.experience = (BigInteger)experience << shift >> 16; pending = 0uL; SetScaledCost(BigInteger.Max(BigInteger.One << 16, (BigInteger)nextLevelCost << shift)); SettleLevelUps(in settings); } private void SetScaledCost(BigInteger value) { scaledCost = value; cost = BigInteger.Max(BigInteger.One, scaledCost >> 16); } private void ClearAtCap() { if (!experience.IsZero || pending != 0L) { experience = BigInteger.Zero; pending = 0uL; Refresh(); } } private void SettleLevelUps(in LevelSettings settings) { while (Level < settings.MaxLevel && experience >= cost) { if (settings.IsFlat) { ulong num = (ulong)((long)settings.MaxLevel - (long)Level + settings.LevelsPerLevelUp - 1) / (ulong)settings.LevelsPerLevelUp; BigInteger bigInteger = BigInteger.Min(experience / cost, num); experience -= bigInteger * cost; Level = (uint)BigInteger.Min(Level + bigInteger * settings.LevelsPerLevelUp, settings.MaxLevel); } else if (!TryBulkLevelUps(in settings)) { experience -= cost; Level = (uint)Math.Min((ulong)Level + (ulong)settings.LevelsPerLevelUp, settings.MaxLevel); SetScaledCost(scaledCost * settings.Growth / 1000); } } if (Level >= settings.MaxLevel) { experience = BigInteger.Zero; } Refresh(); } private bool TryBulkLevelUps(in LevelSettings settings) { if (cost < BigInteger.One << 20) { return false; } double num = (double)settings.Growth / 1000.0; double num2 = Math.Log(num, 2.0); double num3 = Math.Log(num - 1.0, 2.0); double num4 = BigInteger.Log(experience, 2.0) - BigInteger.Log(cost, 2.0) + num3; double num5 = Math.Floor(((num4 > 50.0) ? num4 : Math.Log(1.0 + Math.Pow(2.0, num4), 2.0)) / num2) - 2.0; if (double.IsNaN(num5) || num5 < 64.0) { return false; } ulong num6 = (ulong)((long)settings.MaxLevel - (long)Level + settings.LevelsPerLevelUp - 1) / (ulong)settings.LevelsPerLevelUp; ulong num7 = ((num5 >= (double)num6) ? num6 : ((ulong)num5)); double num8 = (double)num7 * num2; double num9 = ((num8 > 50.0) ? num8 : Math.Log(Math.Pow(2.0, num8) - 1.0, 2.0)); BigInteger bigInteger = BigMath.MultiplyByPowerOfTwo(scaledCost, num9 - num3) >> 16; if (bigInteger.Sign <= 0 || bigInteger > experience) { return false; } experience -= bigInteger; Level = (uint)Math.Min(Level + num7 * settings.LevelsPerLevelUp, settings.MaxLevel); SetScaledCost(BigMath.MultiplyByPowerOfTwo(scaledCost, num8)); return true; } private void Refresh() { BigInteger bigInteger = cost - experience; room = ((bigInteger.Sign <= 0) ? 0 : ((bigInteger.CompareTo(ulong.MaxValue) >= 0) ? ulong.MaxValue : ((ulong)bigInteger))); progressShift = ((!(cost <= long.MaxValue)) ? (BigMath.ApproximateBitLength(cost) - 62) : 0); progressCost = (ulong)(cost >> progressShift); progressExperience = (ulong)BigInteger.Min(experience >> progressShift, progressCost); packShift = ((!(scaledCost <= long.MaxValue)) ? (BigMath.ApproximateBitLength(scaledCost) - 62) : 0); packCost = (ulong)(scaledCost >> packShift); packExperience = (ulong)BigInteger.Min(experience << 16 >> packShift, packCost); } private static ulong ShiftRight(ulong value, int bits) { if (bits < 64) { return value >> bits; } return 0uL; } private static BigInteger ScaledCostAfter(ulong levelUps, in LevelSettings settings) { BigInteger bigInteger = (BigInteger)settings.InitialCost << 16; if (levelUps == 0L || settings.IsFlat) { return bigInteger; } double bits = Math.Min((double)levelUps * Math.Log((double)settings.Growth / 1000.0, 2.0), 16777216.0); return BigMath.MultiplyByPowerOfTwo(bigInteger, bits); } } internal static class BigMath { public static BigInteger Multiply(BigInteger value, double factor) { if (double.IsNaN(factor) || double.IsInfinity(factor) || factor <= 0.0) { return BigInteger.Zero; } long num = BitConverter.DoubleToInt64Bits(factor); int num2 = (int)((num >> 52) & 0x7FF); long num3 = num & 0xFFFFFFFFFFFFFL; if (num2 == 0) { num2 = 1; } else { num3 |= 0x10000000000000L; } num2 -= 1075; BigInteger bigInteger = value * num3; if (num2 < 0) { return bigInteger >> -num2; } return bigInteger << num2; } public static BigInteger MultiplyByPowerOfTwo(BigInteger value, double bits) { double num = Math.Floor(bits); BigInteger bigInteger = Multiply(value, Math.Pow(2.0, bits - num)); int num2 = (int)Math.Max(-2147483648.0, Math.Min(2147483647.0, num)); if (num2 < 0) { return bigInteger >> -num2; } return bigInteger << num2; } public static double Divide(BigInteger numerator, BigInteger denominator) { if (numerator.Sign <= 0 || denominator.Sign <= 0) { return 0.0; } int num = Math.Max(ApproximateBitLength(numerator), ApproximateBitLength(denominator)) - 1000; if (num > 0) { numerator >>= num; denominator >>= num; if (denominator.IsZero) { return double.PositiveInfinity; } } return (double)numerator / (double)denominator; } public static int ApproximateBitLength(BigInteger value) { if (value.Sign > 0) { return (int)Math.Ceiling(BigInteger.Log(value, 2.0)); } return 0; } } internal static class LevelUpEffectHooks { [CompilerGenerated] private static class <>O { public static hook_OnCharacterLevelUp <0>__OnCharacterLevelUp; public static hook_OnTeamLevelUp <1>__OnTeamLevelUp; } private static readonly Dictionary<CharacterBody, float> lastRing = new Dictionary<CharacterBody, float>(); private static readonly Dictionary<CharacterBody, float> lastBeadFlash = new Dictionary<CharacterBody, float>(); private static float lastSound = float.NegativeInfinity; public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__OnCharacterLevelUp; if (obj == null) { hook_OnCharacterLevelUp val = OnCharacterLevelUp; <>O.<0>__OnCharacterLevelUp = val; obj = (object)val; } LevelUpEffectManager.OnCharacterLevelUp += (hook_OnCharacterLevelUp)obj; object obj2 = <>O.<1>__OnTeamLevelUp; if (obj2 == null) { hook_OnTeamLevelUp val2 = OnTeamLevelUp; <>O.<1>__OnTeamLevelUp = val2; obj2 = (object)val2; } LevelUpEffectManager.OnTeamLevelUp += (hook_OnTeamLevelUp)obj2; CharacterBody.onBodyDestroyGlobal += delegate(CharacterBody body) { lastRing.Remove(body); lastBeadFlash.Remove(body); }; Run.onRunStartGlobal += delegate { lastRing.Clear(); lastBeadFlash.Clear(); lastSound = float.NegativeInfinity; }; } public static bool CanShowBeadFlash(CharacterBody body) { if (UncapPlayerLevel.beadEffect.Value) { return IsDue(lastBeadFlash, body, UncapPlayerLevel.beadEffectInterval); } return false; } private static void OnCharacterLevelUp(orig_OnCharacterLevelUp orig, CharacterBody characterBody) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)characterBody) || !Object.op_Implicit((Object)(object)characterBody.teamComponent) || (int)characterBody.teamComponent.teamIndex != 1 || (UncapPlayerLevel.levelUpEffect.Value && IsDue(lastRing, characterBody, UncapPlayerLevel.levelUpEffectInterval))) { orig.Invoke(characterBody); } } private static void OnTeamLevelUp(orig_OnTeamLevelUp orig, TeamIndex teamIndex) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((int)teamIndex == 1) { if (!UncapPlayerLevel.levelUpSound.Value) { return; } int value = UncapPlayerLevel.levelUpSoundInterval.Value; if (value > 0) { if (Time.unscaledTime - lastSound < (float)value) { return; } lastSound = Time.unscaledTime; } } orig.Invoke(teamIndex); } private static bool IsDue(Dictionary<CharacterBody, float> lastShown, CharacterBody body, ConfigEntry<int> intervalSetting) { int value = intervalSetting.Value; if (value <= 0 || !Object.op_Implicit((Object)(object)body)) { return true; } if (lastShown.TryGetValue(body, out var value2) && Time.unscaledTime - value2 < (float)value) { return false; } lastShown[body] = Time.unscaledTime; return true; } } 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); } } internal static class PrayerBeadHooks { private sealed class WrittenBeads { public LevelProgress beads; public uint level; public ulong experience; public ulong nextLevelCost; public uint storage; public bool IsStillIn(CharacterMaster master) { if (master.oldBeadLevel == level && master.beadExperience == experience && master.beadXPNeededForCurrentLevel == nextLevelCost) { return master.newBeadLevel == storage; } return false; } } [CompilerGenerated] private static class <>O { public static hook_TrackBeadExperience <0>__TrackBeadExperience; public static hook_OnBeadReset <1>__OnBeadReset; public static hook_OnBodyStart <2>__OnBodyStart; } private const uint UNCAPPED_FLAG = 2147483648u; private const int MAX_SHIFT = 16777216; private static readonly Dictionary<CharacterMaster, WrittenBeads> written = new Dictionary<CharacterMaster, WrittenBeads>(); public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown object obj = <>O.<0>__TrackBeadExperience; if (obj == null) { hook_TrackBeadExperience val = TrackBeadExperience; <>O.<0>__TrackBeadExperience = val; obj = (object)val; } CharacterMaster.TrackBeadExperience += (hook_TrackBeadExperience)obj; object obj2 = <>O.<1>__OnBeadReset; if (obj2 == null) { hook_OnBeadReset val2 = OnBeadReset; <>O.<1>__OnBeadReset = val2; obj2 = (object)val2; } CharacterMaster.OnBeadReset += (hook_OnBeadReset)obj2; object obj3 = <>O.<2>__OnBodyStart; if (obj3 == null) { hook_OnBodyStart val3 = OnBodyStart; <>O.<2>__OnBodyStart = val3; obj3 = (object)val3; } CharacterMaster.OnBodyStart += (hook_OnBodyStart)obj3; Run.onRunStartGlobal += delegate { written.Clear(); }; } public static void GiveTeamExperience(TeamIndex teamIndex, BigInteger amount) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) if ((int)teamIndex != 1) { return; } ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(teamIndex); for (int i = 0; i < teamMembers.Count; i++) { CharacterBody component = ((Component)teamMembers[i]).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.master)) { GiveExperience(component.master, amount); } } } private static bool TryGetFactors(CharacterMaster master, out ulong bonusFactor, out ulong penaltyFactor) { int num = (Object.op_Implicit((Object)(object)master.inventory) ? master.inventory.GetItemCountEffective(Items.ExtraStatsOnLevelUp) : 0); bonusFactor = (ulong)(0.25f * (float)(num - 1)); penaltyFactor = (ulong)(0.025f * (float)Math.Max(0, master.numberOfBeadStatsGained_XPGainNerf)); return num > 0; } private static void GiveExperience(CharacterMaster master, ulong amount) { if (!TryGetFactors(master, out var bonusFactor, out var penaltyFactor)) { return; } if (amount > ulong.MaxValue / (bonusFactor + 1) || (penaltyFactor != 0 && amount > ulong.MaxValue / penaltyFactor)) { GiveExperience(master, (BigInteger)amount); return; } ulong num = amount + amount * bonusFactor; ulong num2 = amount * penaltyFactor; if (num2 >= num) { num2 = num - (ulong)((long)(num / 5) + (long)((num % 5 != 0) ? 1 : 0)); } LevelSettings settings = UncapPlayerLevel.BeadSettings; LevelProgress levelProgress = Read(master, in settings); uint level = levelProgress.Level; levelProgress.AddExperience(num - num2, in settings); OnExperienceAdded(master, levelProgress, level); } private static void GiveExperience(CharacterMaster master, BigInteger amount) { if (TryGetFactors(master, out var bonusFactor, out var penaltyFactor)) { BigInteger bigInteger = amount * bonusFactor; BigInteger bigInteger2 = amount * penaltyFactor; if (bigInteger2 >= amount + bigInteger) { bigInteger2 = (amount + bigInteger) * 4 / 5; } LevelSettings settings = UncapPlayerLevel.BeadSettings; LevelProgress levelProgress = Read(master, in settings); uint level = levelProgress.Level; levelProgress.AddExperience(amount + bigInteger - bigInteger2, in settings); OnExperienceAdded(master, levelProgress, level); } } private static void OnExperienceAdded(CharacterMaster master, LevelProgress beads, uint oldLevel) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) Write(master, beads); if (beads.Level <= oldLevel) { return; } CharacterBody body = master.GetBody(); if (Object.op_Implicit((Object)(object)body)) { body.SetBuffCount(Buffs.ExtraStatsOnLevelUpBuff.buffIndex, GetBuffCount(beads)); if (LevelUpEffectHooks.CanShowBeadFlash(body)) { SpawnLevelUpEffect(body); } } } private static int GetBuffCount(LevelProgress beads) { return (int)Math.Min(beads.Level - 1, 2147483647u); } private static LevelProgress Read(CharacterMaster master, in LevelSettings settings) { if (written.TryGetValue(master, out var value) && value.IsStillIn(master)) { return value.beads; } LevelProgress levelProgress = new LevelProgress(in settings); if ((master.newBeadLevel & 0x80000000u) != 0) { int shift = (int)Math.Min(master.newBeadLevel & 0x7FFFFFFF, 16777216u); levelProgress.Unpack(master.oldBeadLevel, master.beadExperience, master.beadXPNeededForCurrentLevel, shift, in settings); } else { levelProgress.AddExperience(master.beadExperience, in settings); } return levelProgress; } private static void Write(CharacterMaster master, LevelProgress beads) { ulong experience; ulong nextLevelCost; int num = beads.Pack(out experience, out nextLevelCost); master.oldBeadLevel = beads.Level; master.beadExperience = experience; master.beadXPNeededForCurrentLevel = nextLevelCost; master.newBeadLevel = (uint)(int.MinValue | num); if (!written.TryGetValue(master, out var value)) { value = new WrittenBeads(); written[master] = value; } value.beads = beads; value.level = master.oldBeadLevel; value.experience = master.beadExperience; value.nextLevelCost = master.beadXPNeededForCurrentLevel; value.storage = master.newBeadLevel; } private static void SpawnLevelUpEffect(CharacterBody body) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown float num = 1f; HullClassification hullClassification = body.hullClassification; if ((int)hullClassification != 1) { if ((int)hullClassification == 2) { num = 2.5f; } } else { num = 1.5f; } num += Util.ConvertAmplificationPercentageIntoReductionNormalized((float)body.GetBuffCount(Buffs.ExtraStatsOnLevelUpBuff) * 0.1f); EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ExtraStatsOnLevelUpEffect"), new EffectData { origin = body.footPosition, scale = num }, true); } private static void TrackBeadExperience(orig_TrackBeadExperience orig, CharacterMaster self, ulong amount) { GiveExperience(self, amount); } private static void OnBeadReset(orig_OnBeadReset orig, CharacterMaster self, bool gainedStats) { uint val = (uint)(int.MaxValue - Math.Max(0, self.numberOfBeadStatsGained_XPGainNerf)); self.oldBeadLevel = Math.Min(self.oldBeadLevel, val); orig.Invoke(self, gainedStats); if (NetworkServer.active) { Write(self, new LevelProgress(UncapPlayerLevel.BeadSettings)); } } private static void OnBodyStart(orig_OnBodyStart orig, CharacterMaster self, CharacterBody body) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, body); if (NetworkServer.active && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)self.inventory) && self.inventory.GetItemCountEffective(Items.ExtraStatsOnLevelUp) > 0) { body.SetBuffCount(Buffs.ExtraStatsOnLevelUpBuff.buffIndex, GetBuffCount(Read(self, UncapPlayerLevel.BeadSettings))); } } } internal static class ProperSaveCompat { public const string GUID = "com.KingEnderBrine.ProperSave"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.KingEnderBrine.ProperSave"); public static bool IsLoading { [MethodImpl(MethodImplOptions.NoInlining)] get { return Loading.IsLoading; } } [MethodImpl(MethodImplOptions.NoInlining)] public static void Init() { SaveFile.OnGatherSaveData += GatherSaveData; } [MethodImpl(MethodImplOptions.NoInlining)] public static bool TryLoad(LevelProgress[] teams, in LevelSettings settings) { if (!Loading.IsLoading || Loading.CurrentSave == null) { return false; } try { ProperSaveModel properSaveModel = Loading.CurrentSave.TryGetModdedData<ProperSaveModel>("UncapPlayerLevel.DATA"); if (properSaveModel != null && properSaveModel.TryApplyTo(teams, in settings)) { Log.Info("Loaded the team levels from the save file"); return true; } } catch (Exception arg) { Log.Error($"Couldn't read the team levels from the save file: {arg}"); } Log.Warning("The save file has no team levels in it, they will be worked out from the XP the game saved instead"); return false; } private static void GatherSaveData(Dictionary<string, object> dictionary) { if (TeamManagerHooks.TryCreateSaveData(out var model)) { dictionary["UncapPlayerLevel.DATA"] = model; } } } internal class ProperSaveModel { public const string SAVE_KEY = "UncapPlayerLevel.DATA"; public string[] TeamExperience { get; set; } public string[] TeamNextLevelExperience { get; set; } public uint[] TeamLevel { get; set; } public static ProperSaveModel From(LevelProgress[] teams) { return new ProperSaveModel { TeamExperience = teams.Select((LevelProgress team) => team.Experience.ToString()).ToArray(), TeamNextLevelExperience = teams.Select((LevelProgress team) => team.NextLevelCost.ToString()).ToArray(), TeamLevel = teams.Select((LevelProgress team) => team.Level).ToArray() }; } public bool TryApplyTo(LevelProgress[] teams, in LevelSettings settings) { if (TeamExperience == null || TeamNextLevelExperience == null || TeamLevel == null) { return false; } int num = Math.Min(teams.Length, Math.Min(TeamLevel.Length, Math.Min(TeamExperience.Length, TeamNextLevelExperience.Length))); BigInteger[] array = new BigInteger[num]; BigInteger[] array2 = new BigInteger[num]; for (int i = 0; i < num; i++) { if (!BigInteger.TryParse(TeamExperience[i], out array[i]) || !BigInteger.TryParse(TeamNextLevelExperience[i], out array2[i])) { return false; } } for (int j = 0; j < num; j++) { teams[j].Restore(TeamLevel[j], array[j], array2[j], in settings); } return true; } } internal static class RiskOfOptionsCompat { public const string GUID = "com.rune580.riskofoptions"; private const string ICON_FILE = "icon.png"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining)] public static void Init(string pluginLocation) { //IL_0024: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) //IL_0075: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_007f: 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_008b: Expected O, but got Unknown //IL_0090: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_009a: 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_00a6: Expected O, but got Unknown //IL_00ab: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0106: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0110: 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_011c: Expected O, but got Unknown //IL_0121: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_013c: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown //IL_0157: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_0170: 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_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Expected O, but got Unknown //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Expected O, but got Unknown //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Expected O, but got Unknown //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Expected O, but got Unknown ModSettingsManager.SetModDescription("Removes the level cap of 94 and lets you change how much XP a level costs. Only the host's settings count."); Sprite val = LoadIcon(pluginLocation); if (Object.op_Implicit((Object)(object)val)) { ModSettingsManager.SetModIcon(val); } ModSettingsManager.AddOption((BaseOption)new IntSliderOption(UncapPlayerLevel.initialPlayerLevelCost, new IntSliderConfig { min = 1, max = 1024 })); ModSettingsManager.AddOption((BaseOption)new SliderOption(UncapPlayerLevel.playerXpMultiplier, new SliderConfig { min = 100f, max = 1000f, FormatString = "{0:0.#}%" })); ConfigEntry<int> maxPlayerLevel = UncapPlayerLevel.maxPlayerLevel; IntFieldConfig val2 = new IntFieldConfig(); ((NumericFieldConfig<int>)val2).Min = 1; ModSettingsManager.AddOption((BaseOption)new IntFieldOption(maxPlayerLevel, val2)); ConfigEntry<int> playerLevelPerLevelUps = UncapPlayerLevel.playerLevelPerLevelUps; IntFieldConfig val3 = new IntFieldConfig(); ((NumericFieldConfig<int>)val3).Min = 1; ModSettingsManager.AddOption((BaseOption)new IntFieldOption(playerLevelPerLevelUps, val3)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(UncapPlayerLevel.initialBeadLevelCost, new IntSliderConfig { min = 1, max = 1024 })); ModSettingsManager.AddOption((BaseOption)new SliderOption(UncapPlayerLevel.beadXpMultiplier, new SliderConfig { min = 100f, max = 1000f, FormatString = "{0:0.#}%" })); ConfigEntry<int> maxBeadLevel = UncapPlayerLevel.maxBeadLevel; IntFieldConfig val4 = new IntFieldConfig(); ((NumericFieldConfig<int>)val4).Min = 1; ModSettingsManager.AddOption((BaseOption)new IntFieldOption(maxBeadLevel, val4)); ConfigEntry<int> beadLevelPerLevelUps = UncapPlayerLevel.beadLevelPerLevelUps; IntFieldConfig val5 = new IntFieldConfig(); ((NumericFieldConfig<int>)val5).Min = 1; ModSettingsManager.AddOption((BaseOption)new IntFieldOption(beadLevelPerLevelUps, val5)); ConfigEntry<int> solitudePearlLevel = UncapPlayerLevel.solitudePearlLevel; IntFieldConfig val6 = new IntFieldConfig(); ((NumericFieldConfig<int>)val6).Min = 1; ModSettingsManager.AddOption((BaseOption)new IntFieldOption(solitudePearlLevel, val6)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(UncapPlayerLevel.levelUpEffect)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(UncapPlayerLevel.levelUpEffectInterval, new IntSliderConfig { min = 0, max = 60 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(UncapPlayerLevel.levelUpSound)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(UncapPlayerLevel.levelUpSoundInterval, new IntSliderConfig { min = 0, max = 60 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(UncapPlayerLevel.beadEffect)); ModSettingsManager.AddOption((BaseOption)new IntSliderOption(UncapPlayerLevel.beadEffectInterval, new IntSliderConfig { min = 0, max = 60 })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(UncapPlayerLevel.debugKeys)); ModSettingsManager.AddOption((BaseOption)new KeyBindOption(UncapPlayerLevel.spawnPrayerBeadsKey)); ModSettingsManager.AddOption((BaseOption)new KeyBindOption(UncapPlayerLevel.spawnSolitudeKey)); ModSettingsManager.AddOption((BaseOption)new KeyBindOption(UncapPlayerLevel.spawnBrittleCrownKey)); } private static Sprite LoadIcon(string pluginLocation) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) string directoryName = Path.GetDirectoryName(pluginLocation); string path = Path.Combine(directoryName, "icon.png"); if (!File.Exists(path)) { path = Path.Combine(Path.GetDirectoryName(directoryName), "icon.png"); } if (!File.Exists(path)) { return null; } Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { return null; } 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 SolitudeHooks { [CompilerGenerated] private static class <>O { public static hook_GiveMoneyWithOnLevelUpFreeUnlock <0>__GiveMoneyWithOnLevelUpFreeUnlock; public static hook_OnCalculatedLevelChanged <1>__OnCalculatedLevelChanged; public static hook_LevelThresholdCheck <2>__LevelThresholdCheck; } public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown object obj = <>O.<0>__GiveMoneyWithOnLevelUpFreeUnlock; if (obj == null) { hook_GiveMoneyWithOnLevelUpFreeUnlock val = GiveMoneyWithOnLevelUpFreeUnlock; <>O.<0>__GiveMoneyWithOnLevelUpFreeUnlock = val; obj = (object)val; } CharacterMaster.GiveMoneyWithOnLevelUpFreeUnlock += (hook_GiveMoneyWithOnLevelUpFreeUnlock)obj; object obj2 = <>O.<1>__OnCalculatedLevelChanged; if (obj2 == null) { hook_OnCalculatedLevelChanged val2 = OnCalculatedLevelChanged; <>O.<1>__OnCalculatedLevelChanged = val2; obj2 = (object)val2; } CharacterBody.OnCalculatedLevelChanged += (hook_OnCalculatedLevelChanged)obj2; object obj3 = <>O.<2>__LevelThresholdCheck; if (obj3 == null) { hook_LevelThresholdCheck val3 = LevelThresholdCheck; <>O.<2>__LevelThresholdCheck = val3; obj3 = (object)val3; } OnLevelUpFreeUnlockBehavior.LevelThresholdCheck += (hook_LevelThresholdCheck)obj3; } private static void OnCalculatedLevelChanged(orig_OnCalculatedLevelChanged orig, CharacterBody self, float oldLevel, float newLevel) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_008a: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, oldLevel, newLevel); double num = Math.Floor(newLevel) - Math.Floor(oldLevel) - 1.0; if (!NetworkServer.active || oldLevel < 1f || num < 1.0 || !Object.op_Implicit((Object)(object)self.inventory)) { return; } int itemCountEffective = self.inventory.GetItemCountEffective(Items.OnLevelUpFreeUnlock); if (itemCountEffective > 0) { BuffIndex buffIndex = Buffs.FreeUnlocks.buffIndex; int buffCount = self.GetBuffCount(buffIndex); int num2 = (int)Math.Min(num * (double)itemCountEffective, int.MaxValue - buffCount); self.SetBuffCount(buffIndex, buffCount + num2); if (Object.op_Implicit((Object)(object)self.master)) { self.master.trackedFreeUnlocks = (uint)Math.Min((ulong)self.master.trackedFreeUnlocks + (ulong)(uint)num2, 2147483647uL); } } } private static void LevelThresholdCheck(orig_LevelThresholdCheck orig, OnLevelUpFreeUnlockBehavior self) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0055: Unknown result type (might be due to invalid IL or missing references) if (!(((BaseItemBodyBehavior)self).body.level < (float)UncapPlayerLevel.SolitudePearlLevel)) { ItemTransformation val = default(ItemTransformation); ((ItemTransformation)(ref val)).originalItemIndex = Items.OnLevelUpFreeUnlock.itemIndex; ((ItemTransformation)(ref val)).newItemIndex = Items.Pearl.itemIndex; ((ItemTransformation)(ref val)).maxToTransform = ((BaseItemBodyBehavior)self).stack; val.transformationType = (ItemTransformationTypeIndex)0; ItemTransformation val2 = val; TryTransformResult val3 = default(TryTransformResult); ((ItemTransformation)(ref val2)).TryTransform(((BaseItemBodyBehavior)self).body.inventory, ref val3); } } private static void GiveMoneyWithOnLevelUpFreeUnlock(orig_GiveMoneyWithOnLevelUpFreeUnlock orig, CharacterMaster self, uint amount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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) if (!TeamManagerHooks.TryGetNextLevelCost(self.teamIndex, out var cost)) { orig.Invoke(self, amount); return; } self.moneyEarnedSoFar += (float)amount; CharacterBody body = self.GetBody(); if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.inventory) || CharacterMaster.costOfSmallChest == 0) { return; } int num = Math.Max(1, Math.Min(body.inventory.GetItemCountEffective(Items.OnLevelUpFreeUnlock), (int)CharacterMaster.maxStacks)); double num2 = (double)(CharacterMaster.chestPerLevelFactor + (float)(num - 1) * CharacterMaster.stackingBonus) / (double)CharacterMaster.costOfSmallChest; BigInteger bigInteger = BigMath.Multiply(cost, num2 * (double)self.moneyEarnedSoFar); if (bigInteger.Sign > 0) { double num3 = Math.Ceiling(BigMath.Divide(bigInteger, cost) / num2); self.moneyEarnedSoFar = (float)Math.Max(0.0, (double)self.moneyEarnedSoFar - num3); BigInteger bigInteger2 = BigInteger.Zero; if (Object.op_Implicit((Object)(object)ExperienceManager.instance)) { bigInteger2 = BigInteger.Min(bigInteger, CharacterMaster.maxXPDisplay); Vector3 val = body.transform.position + CharacterMaster.RandomPointOnUnitSphere() * CharacterMaster.orbSpawnDistance; ExperienceManager.instance.AwardExperience(val, body, (ulong)bigInteger2); } TeamManagerHooks.GiveExperience(self.teamIndex, bigInteger - bigInteger2); } } } internal static class TeamManagerHooks { [CompilerGenerated] private static class <>O { public static hook_Start <0>__Start; public static hook_GiveTeamExperience <1>__GiveTeamExperience; public static hook_SetTeamExperience <2>__SetTeamExperience; public static hook_SetTeamLevel <3>__SetTeamLevel; public static hook_OnSerialize <4>__OnSerialize; public static hook_OnDeserialize <5>__OnDeserialize; } private static LevelProgress[] teams = Array.Empty<LevelProgress>(); private static bool ignoreSaveReplay; public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //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_009b: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown object obj = <>O.<0>__Start; if (obj == null) { hook_Start val = Start; <>O.<0>__Start = val; obj = (object)val; } TeamManager.Start += (hook_Start)obj; object obj2 = <>O.<1>__GiveTeamExperience; if (obj2 == null) { hook_GiveTeamExperience val2 = GiveTeamExperience; <>O.<1>__GiveTeamExperience = val2; obj2 = (object)val2; } TeamManager.GiveTeamExperience += (hook_GiveTeamExperience)obj2; object obj3 = <>O.<2>__SetTeamExperience; if (obj3 == null) { hook_SetTeamExperience val3 = SetTeamExperience; <>O.<2>__SetTeamExperience = val3; obj3 = (object)val3; } TeamManager.SetTeamExperience += (hook_SetTeamExperience)obj3; object obj4 = <>O.<3>__SetTeamLevel; if (obj4 == null) { hook_SetTeamLevel val4 = SetTeamLevel; <>O.<3>__SetTeamLevel = val4; obj4 = (object)val4; } TeamManager.SetTeamLevel += (hook_SetTeamLevel)obj4; object obj5 = <>O.<4>__OnSerialize; if (obj5 == null) { hook_OnSerialize val5 = OnSerialize; <>O.<4>__OnSerialize = val5; obj5 = (object)val5; } TeamManager.OnSerialize += (hook_OnSerialize)obj5; object obj6 = <>O.<5>__OnDeserialize; if (obj6 == null) { hook_OnDeserialize val6 = OnDeserialize; <>O.<5>__OnDeserialize = val6; obj6 = (object)val6; } TeamManager.OnDeserialize += (hook_OnDeserialize)obj6; } public static bool TryGetNextLevelCost(TeamIndex teamIndex, out BigInteger cost) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) LevelProgress team; bool flag = TryGetTeam(teamIndex, out team); cost = (flag ? team.NextLevelCost : BigInteger.Zero); return flag; } public static void GiveExperience(TeamIndex teamIndex, BigInteger amount) { //IL_0052: 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_004a: Unknown result type (might be due to invalid IL or missing references) TeamManager instance = TeamManager.instance; if (Object.op_Implicit((Object)(object)instance) && amount.Sign > 0) { if (amount > ulong.MaxValue && TryGetTeam(teamIndex, out var team)) { BigInteger amount2 = amount - ulong.MaxValue; team.AddExperience(amount2, UncapPlayerLevel.Settings); PrayerBeadHooks.GiveTeamExperience(teamIndex, amount2); } instance.GiveTeamExperience(teamIndex, (ulong)BigInteger.Min(amount, ulong.MaxValue)); } } public static bool TryCreateSaveData(out ProperSaveModel model) { model = ((NetworkServer.active && teams.Length != 0) ? ProperSaveModel.From(teams) : null); return model != null; } private static bool TryGetTeam(TeamIndex teamIndex, out LevelProgress team) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown int num = (int)teamIndex; team = ((NetworkServer.active && num >= 0 && num < teams.Length) ? teams[num] : null); return team != null; } private static void Start(orig_Start orig, TeamManager self) { if (NetworkServer.active) { LevelSettings settings = UncapPlayerLevel.Settings; teams = new LevelProgress[self.teamLevels.Length]; for (int i = 0; i < teams.Length; i++) { teams[i] = new LevelProgress(in settings); } ignoreSaveReplay = ProperSaveCompat.Enabled && ProperSaveCompat.TryLoad(teams, in settings); } orig.Invoke(self); } private static void GiveTeamExperience(orig_GiveTeamExperience orig, TeamManager self, TeamIndex teamIndex, ulong experience) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 if (TryGetTeam(teamIndex, out var team)) { if (ignoreSaveReplay && (int)teamIndex == 1 && ProperSaveCompat.IsLoading) { ignoreSaveReplay = false; } else { team.AddExperience(experience, UncapPlayerLevel.Settings); } } orig.Invoke(self, teamIndex, experience); } private static void SetTeamExperience(orig_SetTeamExperience orig, TeamManager self, TeamIndex teamIndex, ulong newExperience) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (TryGetTeam(teamIndex, out var team)) { Publish(self, teamIndex, team); } } private static void SetTeamLevel(orig_SetTeamLevel orig, TeamManager self, TeamIndex teamIndex, uint newLevel) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (TryGetTeam(teamIndex, out var team) && team.Level != newLevel) { team.SetLevel(newLevel, UncapPlayerLevel.Settings); Publish(self, teamIndex, team); } } private static bool OnSerialize(orig_OnSerialize orig, TeamManager self, NetworkWriter writer, bool initialState) { int num = self.teamLevels.Length; uint num2 = (initialState ? ((uint)((1 << num) - 1)) : ((NetworkBehaviour)self).syncVarDirtyBits); writer.WritePackedUInt32(num2); if (num2 == 0) { return false; } for (int i = 0; i < num; i++) { if ((num2 & (uint)(1 << i)) != 0) { writer.WritePackedUInt32(self.teamLevels[i]); writer.WritePackedUInt64(self.teamExperience[i]); writer.WritePackedUInt64(self.teamNextLevelExperience[i]); } } return true; } private static void OnDeserialize(orig_OnDeserialize orig, TeamManager self, NetworkReader reader, bool initialState) { int num = self.teamLevels.Length; uint num2 = reader.ReadPackedUInt32(); for (int i = 0; i < num; i++) { if ((num2 & (uint)(1 << i)) != 0) { uint level = reader.ReadPackedUInt32(); ulong experience = reader.ReadPackedUInt64(); ulong nextLevelExperience = reader.ReadPackedUInt64(); Apply(self, (TeamIndex)(sbyte)i, level, experience, nextLevelExperience); } } } private static void Publish(TeamManager teamManager, TeamIndex teamIndex, LevelProgress team) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) team.GetProgress(out var experience, out var nextLevelExperience); Apply(teamManager, teamIndex, team.Level, experience, nextLevelExperience); ((NetworkBehaviour)teamManager).SetDirtyBit((uint)(1 << (int)teamIndex)); } private static void Apply(TeamManager teamManager, TeamIndex teamIndex, uint level, ulong experience, ulong nextLevelExperience) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Expected I4, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) int num = (int)teamIndex; teamManager.teamExperience[num] = experience; teamManager.teamCurrentLevelExperience[num] = 0uL; teamManager.teamNextLevelExperience[num] = nextLevelExperience; uint num2 = teamManager.teamLevels[num]; if (num2 == level) { return; } ReadOnlyCollection<TeamComponent> teamMembers = TeamComponent.GetTeamMembers(teamIndex); for (int i = 0; i < teamMembers.Count; i++) { CharacterBody component = ((Component)teamMembers[i]).GetComponent<CharacterBody>(); if (Object.op_Implicit((Object)(object)component)) { component.OnTeamLevelChanged(); } } teamManager.teamLevels[num] = level; if (num2 < level) { GlobalEventManager.OnTeamLevelUp(teamIndex); } } } [BepInPlugin("360gaggi.UncapPlayerLevel", "UncapPlayerLevel", "2.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class UncapPlayerLevel : BaseUnityPlugin { public const string PLUGIN_GUID = "360gaggi.UncapPlayerLevel"; public const string PLUGIN_AUTHOR = "360gaggi"; public const string PLUGIN_NAME = "UncapPlayerLevel"; public const string PLUGIN_VERSION = "2.0.2"; private const string OLD_CONFIG_FILE = "HeroYT.UncapPlayerLevel.cfg"; public const int MIN_INITIAL_LEVEL_COST = 1; public const int MAX_INITIAL_LEVEL_COST = 1024; public const float MIN_XP_MULTIPLICATOR = 100f; public const float MAX_XP_MULTIPLICATOR = 1000f; public const int MAX_LEVEL_UP_EFFECT_INTERVAL = 60; public static ConfigEntry<int> initialPlayerLevelCost; public static ConfigEntry<int> maxPlayerLevel; public static ConfigEntry<int> playerLevelPerLevelUps; public static ConfigEntry<float> playerXpMultiplier; public static ConfigEntry<int> initialBeadLevelCost; public static ConfigEntry<int> maxBeadLevel; public static ConfigEntry<int> beadLevelPerLevelUps; public static ConfigEntry<float> beadXpMultiplier; public static ConfigEntry<int> solitudePearlLevel; public static ConfigEntry<bool> levelUpEffect; public static ConfigEntry<int> levelUpEffectInterval; public static ConfigEntry<bool> levelUpSound; public static ConfigEntry<int> levelUpSoundInterval; public static ConfigEntry<bool> beadEffect; public static ConfigEntry<int> beadEffectInterval; public static ConfigEntry<bool> debugKeys; public static ConfigEntry<KeyboardShortcut> spawnPrayerBeadsKey; public static ConfigEntry<KeyboardShortcut> spawnSolitudeKey; public static ConfigEntry<KeyboardShortcut> spawnBrittleCrownKey; internal static LevelSettings Settings => new LevelSettings(initialPlayerLevelCost.Value, maxPlayerLevel.Value, playerLevelPerLevelUps.Value, playerXpMultiplier.Value); internal static LevelSettings BeadSettings => new LevelSettings(initialBeadLevelCost.Value, maxBeadLevel.Value, beadLevelPerLevelUps.Value, beadXpMultiplier.Value); internal static uint SolitudePearlLevel => Math.Min((uint)Math.Max(1, solitudePearlLevel.Value), Settings.MaxLevel); public void Awake() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Expected O, but got Unknown //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Expected O, but got Unknown //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Expected O, but got Unknown //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) Log.Init(((BaseUnityPlugin)this).Logger); KeepOldConfig(); initialPlayerLevelCost = ((BaseUnityPlugin)this).Config.Bind<int>("Player", "Initial level cost", 20, new ConfigDescription("How much XP the first level up costs (vanilla is 20)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1024), Array.Empty<object>())); maxPlayerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Player", "Max level", int.MaxValue, new ConfigDescription("The highest level that can be reached (vanilla stops at 94)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>())); playerLevelPerLevelUps = ((BaseUnityPlugin)this).Config.Bind<int>("Player", "How many levels per level up", 1, new ConfigDescription("How many levels you get per level up (vanilla is 1)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>())); playerXpMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Player", "XP multiplicator", 155f, new ConfigDescription("How much XP a level up costs compared to the one before it, in percent (vanilla is 155%). 100% means every level costs the same", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 1000f), Array.Empty<object>())); initialBeadLevelCost = ((BaseUnityPlugin)this).Config.Bind<int>("Beads", "Initial level cost", 20, new ConfigDescription("How much XP the first level of the Prayer Beads costs (vanilla is 20)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 1024), Array.Empty<object>())); maxBeadLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Beads", "Max level", int.MaxValue, new ConfigDescription("The highest level the Prayer Beads can reach (vanilla stops at 94)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>())); beadLevelPerLevelUps = ((BaseUnityPlugin)this).Config.Bind<int>("Beads", "How many levels per level up", 1, new ConfigDescription("How many levels the Prayer Beads get per level up (vanilla is 1)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>())); beadXpMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Beads", "XP multiplicator", 155f, new ConfigDescription("How much XP a level of the Prayer Beads costs compared to the one before it, in percent (vanilla is 155%). 100% means every level costs the same", (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 1000f), Array.Empty<object>())); solitudePearlLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Solitude", "Pearl level", int.MaxValue, new ConfigDescription("The level at which Longstanding Solitude turns into a Pearl (vanilla is 91). It always does so when the max level of the player is reached, even if this is set higher", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>())); levelUpEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Level up effect", true, "Shows the ring of light a player (or one of their allies) gets when they level up. Turn it off to never see it"); levelUpEffectInterval = ((BaseUnityPlugin)this).Config.Bind<int>("Effects", "Level up effect interval", 1, new ConfigDescription("The least time between two rings of light on the same character, in seconds. Past 94 you can level many times a second. 0 shows every single one like vanilla", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); levelUpSound = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Level up sound", true, "Plays the sound when the players level up. Turn it off to never hear it"); levelUpSoundInterval = ((BaseUnityPlugin)this).Config.Bind<int>("Effects", "Level up sound interval", 1, new ConfigDescription("The least time between two level up sounds, in seconds. 0 plays every single one like vanilla", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); beadEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Effects", "Prayer Beads effect", true, "Shows the golden flash when the Prayer Beads level up. Turn it off to never see it"); beadEffectInterval = ((BaseUnityPlugin)this).Config.Bind<int>("Effects", "Prayer Beads effect interval", 1, new ConfigDescription("The least time between two flashes of the Prayer Beads on the same player, in seconds. 0 shows every single one like vanilla", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>())); debugKeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Debug keys", false, "Turns on the keys below, for trying things out. They only work for the host"); spawnPrayerBeadsKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "Spawn Prayer Beads", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), "Drops Prayer Beads in front of you"); spawnSolitudeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "Spawn Longstanding Solitude", new KeyboardShortcut((KeyCode)284, Array.Empty<KeyCode>()), "Drops a Longstanding Solitude in front of you"); spawnBrittleCrownKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Debug", "Spawn Brittle Crown", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Drops a Brittle Crown in front of you. With a Longstanding Solitude all gold turns into XP, so this is a quick way to a lot of levels"); NetworkModCompatibilityHelper.networkModList = NetworkModCompatibilityHelper.networkModList.Append("360gaggi.UncapPlayerLevel;2.0.2"); TeamManagerHooks.Init(); SolitudeHooks.Init(); PrayerBeadHooks.Init(); KillExperienceHooks.Init(); LevelUpEffectHooks.Init(); if (ProperSaveCompat.Enabled) { ProperSaveCompat.Init(); } if (RiskOfOptionsCompat.Enabled) { RiskOfOptionsCompat.Init(((BaseUnityPlugin)this).Info.Location); } } public void Update() { DebugKeys.Update(); } private void KeepOldConfig() { string text = Path.Combine(Paths.ConfigPath, "HeroYT.UncapPlayerLevel.cfg"); if (!File.Exists(text) || File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath)) { return; } try { File.Move(text, ((BaseUnityPlugin)this).Config.ConfigFilePath); ((BaseUnityPlugin)this).Config.Reload(); } catch (Exception ex) { Log.Warning("Could not take over the old config file: " + ex.Message); } } } }