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 PlayerLevels v0.0.12
PlayerLevels.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using MenuLib.MonoBehaviors; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using Unity.VisualScripting; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Autodesk.Fbx")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")] [assembly: IgnoresAccessChecksTo("Klattersynth")] [assembly: IgnoresAccessChecksTo("Photon3Unity3D")] [assembly: IgnoresAccessChecksTo("PhotonChat")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")] [assembly: IgnoresAccessChecksTo("PhotonVoice.API")] [assembly: IgnoresAccessChecksTo("PhotonVoice")] [assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization")] [assembly: IgnoresAccessChecksTo("Sirenix.Utilities")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("websocket-sharp")] [assembly: AssemblyCompany("WAAAAGH")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.1.7")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PlayerLevels")] [assembly: AssemblyTitle("PlayerLevels")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.7.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 PlayerLevels { [BepInPlugin("WAAAAGH.PlayerLevels", "PlayerLevels", "0.0.12")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PlayerLevels : BaseUnityPlugin { public static ConfigEntry<int> NumberOfUpgradesPerLevel; public static ConfigEntry<int> MaxStaminaGain; public static ConfigEntry<int> MaxHealthGain; public static ConfigEntry<int> MaxStrengthGain; public static ConfigEntry<int> MaxRangeGain; public static ConfigEntry<int> MaxSpeedGain; public static ConfigEntry<int> MaxJumpGain; public static ConfigEntry<int> MaxTumbleLaunchGain; public static ConfigEntry<float> DelayBeforeRegen; public static ConfigEntry<float> StaminaRegenPerLevel; public static ConfigEntry<float> HealthRegenPerLevel; public static ConfigEntry<int> BaseStaminaLevel; public static ConfigEntry<int> BaseHealthLevel; public static ConfigEntry<int> TumbleLevel1Damage; public static ConfigEntry<int> TumbleLevel2Damage; public static ConfigEntry<int> TumbleLevel3Damage; public static ConfigEntry<int> TumbleLevel4Damage; public static ConfigEntry<int> TumbleLevelNDamage; public static ConfigEntry<int> ExpGainedAnimal; public static ConfigEntry<int> ExpGainedRobe; public static ConfigEntry<int> ExpGainedUpscream; public static ConfigEntry<int> ExpGainedGnome; public static ConfigEntry<int> ExpGainedBang; public static ConfigEntry<int> ExpGainedHunter; public static ConfigEntry<int> ExpGainedBowtie; public static ConfigEntry<int> ExpGainedDuck; public static ConfigEntry<int> ExpGainedBeamer; public static ConfigEntry<int> ExpGainedTumbler; public static ConfigEntry<int> ExpGainedFloater; public static ConfigEntry<int> ExpGainedHidden; public static ConfigEntry<int> ExpGainedRunner; public static ConfigEntry<int> ExpGainedSlowMouth; public static ConfigEntry<int> ExpGainedSlowWalker; public static ConfigEntry<int> ExpGainedThinman; public static ConfigEntry<int> ExpGainedValuableThrower; public static ConfigEntry<int> ExpGainedCeilingEye; public static ConfigEntry<int> ExpGainedHeadman; public static ConfigEntry<int> ExpNeededPerLevel; public static ConfigEntry<int> ExpNeededScaling; public static ConfigEntry<bool> ShowPlayerLeaveEvents; public static Dictionary<string, int> KillCounts = new Dictionary<string, int>(); public static int PlayerCurrentLevel = 0; public static ConfigEntry<string> CustomEnemies; public static Dictionary<string, ConfigEntry<int>> ExpGainedCustomEnemies = new Dictionary<string, ConfigEntry<int>>(); internal static PlayerLevels Instance { get; private set; } = null; internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } internal void AddCustomEnemyExpGained(string name, int defaultExpGained) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown ExpGainedCustomEnemies.Add(name, ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains (Custom enemies)", name + " Kill Exp", defaultExpGained, new ConfigDescription("Amount of exp gained for killing " + name, (AcceptableValueBase)null, Array.Empty<object>()))); } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } internal void Patch() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Expected O, but got Unknown //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Expected O, but got Unknown //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Expected O, but got Unknown //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Expected O, but got Unknown //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Expected O, but got Unknown //IL_03c4: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Expected O, but got Unknown //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Expected O, but got Unknown //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Expected O, but got Unknown //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Expected O, but got Unknown //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Expected O, but got Unknown //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Expected O, but got Unknown //IL_04cc: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Expected O, but got Unknown //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Expected O, but got Unknown //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Expected O, but got Unknown //IL_0550: Unknown result type (might be due to invalid IL or missing references) //IL_055a: Expected O, but got Unknown //IL_057c: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Expected O, but got Unknown //IL_05a8: Unknown result type (might be due to invalid IL or missing references) //IL_05b2: Expected O, but got Unknown //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Expected O, but got Unknown //IL_0600: Unknown result type (might be due to invalid IL or missing references) //IL_060a: Expected O, but got Unknown //IL_062c: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Expected O, but got Unknown //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Expected O, but got Unknown //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_0690: Expected O, but got Unknown //IL_0751: Unknown result type (might be due to invalid IL or missing references) //IL_0756: Unknown result type (might be due to invalid IL or missing references) //IL_0759: Expected O, but got Unknown //IL_075e: Expected O, but got Unknown NumberOfUpgradesPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Upgrades received per level up", 2, new ConfigDescription("How many upgrades a player receives when they level up", (AcceptableValueBase)null, Array.Empty<object>())); MaxStaminaGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max stamina gain", 10, new ConfigDescription("Maximum Stamina Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); MaxHealthGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max health gain", 6, new ConfigDescription("Maximum Health Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); MaxStrengthGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max strength gain", 5, new ConfigDescription("Maximum Strength Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); MaxRangeGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max range gain", 4, new ConfigDescription("Maximum Range Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); MaxSpeedGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max speed gain", 3, new ConfigDescription("Maximum Speed Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); MaxJumpGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max jump gain", 4, new ConfigDescription("Maximum Jump Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); MaxTumbleLaunchGain = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Max tumble launch gain", 8, new ConfigDescription("Maximum Tumble Launch Upgrades you can receive at max level", (AcceptableValueBase)null, Array.Empty<object>())); DelayBeforeRegen = ((BaseUnityPlugin)this).Config.Bind<float>("Levelling", "Delay before regen", 5f, new ConfigDescription("Delay before regen", (AcceptableValueBase)null, Array.Empty<object>())); StaminaRegenPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Levelling", "Stamina regen per level", 0.25f, new ConfigDescription("Stamina regen per Stamina Upgrade", (AcceptableValueBase)null, Array.Empty<object>())); HealthRegenPerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Levelling", "Health regen per level", 0.1f, new ConfigDescription("Health regen per Health Upgrade", (AcceptableValueBase)null, Array.Empty<object>())); BaseStaminaLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Base stamina level", 2, new ConfigDescription("Base stamina level (for base regen calculation)", (AcceptableValueBase)null, Array.Empty<object>())); BaseHealthLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Levelling", "Base health level", 1, new ConfigDescription("Base health level (for base regen calculation)", (AcceptableValueBase)null, Array.Empty<object>())); TumbleLevel1Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 1 Tumble Damage", 15, (ConfigDescription)null); TumbleLevel2Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 2 Tumble Damage", 25, (ConfigDescription)null); TumbleLevel3Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 3 Tumble Damage", 35, (ConfigDescription)null); TumbleLevel4Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Level 4 Tumble Damage", 45, (ConfigDescription)null); TumbleLevelNDamage = ((BaseUnityPlugin)this).Config.Bind<int>("Tumble Damage", "Tumble Damage foreach level after 4", 5, (ConfigDescription)null); ExpGainedAnimal = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Animal Kill Exp", 25, new ConfigDescription("Experience gained for killing an Animal enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedRobe = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Robe Kill Exp", 50, new ConfigDescription("Experience gained for killing a Robe enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedUpscream = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Upscream Kill Exp", 25, new ConfigDescription("Experience gained for killing an Upscream enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedGnome = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Gnome Kill Exp", 5, new ConfigDescription("Experience gained for killing a Gnome enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedBang = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Bang Kill Exp", 5, new ConfigDescription("Experience gained for killing a Bang enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedHunter = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Hunter Kill Exp", 50, new ConfigDescription("Experience gained for killing a Hunter enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedBowtie = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Bowtie Kill Exp", 50, new ConfigDescription("Experience gained for killing a Bowtie enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedDuck = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Duck Kill Exp", 25, new ConfigDescription("Experience gained for killing a Duck enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedBeamer = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Beamer Kill Exp", 25, new ConfigDescription("Experience gained for killing a Beamer enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedTumbler = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Tumbler Kill Exp", 20, new ConfigDescription("Experience gained for killing a Tumbler enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedFloater = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Floater Kill Exp", 25, new ConfigDescription("Experience gained for killing a Floater enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedHidden = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Hidden Kill Exp", 35, new ConfigDescription("Experience gained for killing a Hidden enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedRunner = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Runner Kill Exp", 25, new ConfigDescription("Experience gained for killing a Runner enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedSlowMouth = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "SlowMouth Kill Exp", 15, new ConfigDescription("Experience gained for killing a SlowMouth enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedSlowWalker = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "SlowWalker Kill Exp", 100, new ConfigDescription("Experience gained for killing a SlowWalker enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedThinman = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Thinman Kill Exp", 35, new ConfigDescription("Experience gained for killing a Thinman enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedValuableThrower = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "ValuableThrower Kill Exp", 25, new ConfigDescription("Experience gained for killing a ValuableThrower enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedCeilingEye = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "CeilingEye Kill Exp", 40, new ConfigDescription("Experience gained for killing a CeilingEye enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpGainedHeadman = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Headman Kill Exp", 75, new ConfigDescription("Experience gained for killing a Headman enemy", (AcceptableValueBase)null, Array.Empty<object>())); ExpNeededPerLevel = ((BaseUnityPlugin)this).Config.Bind<int>("Experience Gains", "Exp needed to level", 100, new ConfigDescription("Experience needed to level up", (AcceptableValueBase)null, Array.Empty<object>())); ShowPlayerLeaveEvents = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Show player leave notifications", true, new ConfigDescription("Show player leave notifications", (AcceptableValueBase)null, Array.Empty<object>())); CustomEnemies = ((BaseUnityPlugin)this).Config.Bind<string>("Custom Enemies Registry", "Registered custom enemies", "", new ConfigDescription("List of comma ',' delimited enemy names", (AcceptableValueBase)null, Array.Empty<object>())); string value = CustomEnemies.Value; List<string> list = (from enemy in value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select enemy.Trim() into enemy where !string.IsNullOrEmpty(enemy) select enemy).ToList(); foreach (string item in list) { AddCustomEnemyExpGained(item, 100); } if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } public static int GetExpForEnemyType(string enemyType) { switch (enemyType) { case "Animal": return ExpGainedAnimal.Value; case "Robe": return ExpGainedRobe.Value; case "Upscream": return ExpGainedUpscream.Value; case "Gnome": return ExpGainedGnome.Value; case "Banger": return ExpGainedBang.Value; case "Huntsman": return ExpGainedHunter.Value; case "Bowtie": return ExpGainedBowtie.Value; case "Apex Predator": return ExpGainedDuck.Value; case "Clown": return ExpGainedBeamer.Value; case "Chef": return ExpGainedTumbler.Value; case "Mentalist": return ExpGainedFloater.Value; case "Hidden": return ExpGainedHidden.Value; case "Reaper": return ExpGainedRunner.Value; case "Spewer": return ExpGainedSlowMouth.Value; case "Trudge": return ExpGainedSlowWalker.Value; case "Shadow Child": return ExpGainedThinman.Value; case "Rugrat": return ExpGainedValuableThrower.Value; case "Peeper": return ExpGainedCeilingEye.Value; case "Headman": return ExpGainedHeadman.Value; default: if (!ExpGainedCustomEnemies.ContainsKey(enemyType)) { Debug.LogWarning((object)("No exp value for enemy: $" + enemyType + ", enemy is not registered or recognized")); return 100; } return ExpGainedCustomEnemies[enemyType].Value; } } public static int GetExpGainedFromKills() { int num = 0; foreach (KeyValuePair<string, int> killCount in KillCounts) { num += killCount.Value * GetExpForEnemyType(killCount.Key); } return num; } public static int GetExpRequiredForLevelUp(int currentLevel) { return 0; } } public static class CoroutimeManager { } public class PlayerAttributes { private Dictionary<string, int> attributes; public int Stamina { get { return attributes["Stamina"]; } set { attributes["Stamina"] = value; } } public int Health { get { return attributes["Health"]; } set { attributes["Health"] = value; } } public int Strength { get { return attributes["Strength"]; } set { attributes["Strength"] = value; } } public int Range { get { return attributes["Range"]; } set { attributes["Range"] = value; } } public int Speed { get { return attributes["Speed"]; } set { attributes["Speed"] = value; } } public int TumbleLaunch { get { return attributes["Launch"]; } set { attributes["Launch"] = value; } } public int ExtraJump { get { return attributes["Extra Jump"]; } set { attributes["Extra Jump"] = value; } } public PlayerAttributes() { attributes = new Dictionary<string, int> { { "Extra Jump", 0 }, { "Range", 0 }, { "Strength", 0 }, { "Health", 0 }, { "Speed", 0 }, { "Stamina", 0 }, { "Launch", 0 } }; } public PlayerAttributes(Dictionary<string, int> existingAttributes) { attributes = new Dictionary<string, int>(existingAttributes); } public Dictionary<string, int> GetRawAttributes() { return new Dictionary<string, int>(attributes); } } [HarmonyPatch(typeof(PlayerAvatar))] public static class PlayerSpawnPatch { private static bool canUpgrade = false; private static int expCurrent = 0; private static int expPrev = 0; private static int levelsGainedLastRound = 0; private static List<Level> BLACK_LISTED_LEVELS = new List<Level> { RunManager.instance.levelLobby, RunManager.instance.levelLobbyMenu, RunManager.instance.levelMainMenu, RunManager.instance.levelShop, RunManager.instance.levelTutorial }; private static string WeightedRandomSelection(Dictionary<string, int> remaining) { int num = remaining.Values.Sum(); if (num == 0) { return ""; } int num2 = Random.Range(0, num); int num3 = 0; foreach (KeyValuePair<string, int> item in remaining) { num3 += item.Value; if (num2 < num3) { return item.Key; } } return ""; } private static Dictionary<string, int> PickRandomUpgrades(Dictionary<string, int> currentUpgrades, Dictionary<string, int> maximumUpgrades, int numberOfUpgrades) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); foreach (string key in maximumUpgrades.Keys) { int num = maximumUpgrades[key]; int num2 = (currentUpgrades.ContainsKey(key) ? currentUpgrades[key] : 0); int num3 = num - num2; dictionary[key] = ((num3 > 0) ? num3 : 0); } Dictionary<string, int> dictionary2 = new Dictionary<string, int>(); foreach (string key2 in maximumUpgrades.Keys) { dictionary2[key2] = 0; } for (int i = 0; i < numberOfUpgrades; i++) { if (dictionary.Values.Sum() == 0) { break; } string text = WeightedRandomSelection(dictionary); if (text == null) { break; } dictionary2[text]++; dictionary[text]--; } return dictionary2; } public static string? GetSteamID() { try { PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(SemiFunc.PhotonViewIDPlayerAvatarLocal()); if ((Object)(object)val == (Object)null) { return null; } return SemiFunc.PlayerGetSteamID(SemiFunc.PlayerAvatarGetFromPhotonID(SemiFunc.PhotonViewIDPlayerAvatarLocal())); } catch (Exception) { Debug.Log((object)"Error while retrieving steamID"); return null; } } public static Dictionary<string, int>? GetCurrentStats() { string steamID = GetSteamID(); if (steamID == null) { Debug.Log((object)"No valid steamID found, unable to retrieve current stats"); return null; } return StatsManager.instance.FetchPlayerUpgrades(steamID); } private static Dictionary<string, int> GetMaximumStats() { Dictionary<string, int> dictionary = new Dictionary<string, int>(); dictionary["Health"] = PlayerLevels.MaxHealthGain.Value; dictionary["Stamina"] = PlayerLevels.MaxStaminaGain.Value; dictionary["Strength"] = PlayerLevels.MaxStrengthGain.Value; dictionary["Range"] = PlayerLevels.MaxRangeGain.Value; dictionary["Speed"] = PlayerLevels.MaxSpeedGain.Value; dictionary["Extra Jump"] = PlayerLevels.MaxJumpGain.Value; dictionary["Launch"] = PlayerLevels.MaxTumbleLaunchGain.Value; return dictionary; } private static bool ApplyUpgrades(Dictionary<string, int> stats) { string steamID = GetSteamID(); if (steamID == null) { return false; } int num = 0; bool flag = false; foreach (KeyValuePair<string, int> stat in stats) { string key = stat.Key; int value = stat.Value; num += value; for (int i = 0; i < value; i++) { switch (key) { case "Health": PunManager.instance.UpgradePlayerHealth(steamID); flag = true; break; case "Stamina": PunManager.instance.UpgradePlayerEnergy(steamID); flag = true; break; case "Strength": PunManager.instance.UpgradePlayerGrabStrength(steamID); flag = true; break; case "Range": PunManager.instance.UpgradePlayerGrabRange(steamID); flag = true; break; case "Speed": PunManager.instance.UpgradePlayerSprintSpeed(steamID); flag = true; break; case "Extra Jump": PunManager.instance.UpgradePlayerExtraJump(steamID); flag = true; break; case "Launch": PunManager.instance.UpgradePlayerTumbleLaunch(steamID); flag = true; break; default: Debug.Log((object)("Unknown upgrade: " + key)); break; } } } List<string> list = new List<string>(); foreach (KeyValuePair<string, int> stat2 in stats) { if (stat2.Value >= 1) { list.Add($"{stat2.Key} +{stat2.Value}"); } } if (list.Count > 0) { ((MonoBehaviour)UpgradeCoroutineManager.Instance).StartCoroutine(DisplayExperiencedGained(list)); } return num == 0 || flag; } public static bool LevelUp() { Debug.Log((object)"Player has levelled up!"); Dictionary<string, int> currentStats = GetCurrentStats(); if (currentStats == null) { return false; } Dictionary<string, int> maximumStats = GetMaximumStats(); int value = PlayerLevels.NumberOfUpgradesPerLevel.Value; int expGainedFromKills = PlayerLevels.GetExpGainedFromKills(); int num = expGainedFromKills + expCurrent; levelsGainedLastRound = num / Mathf.Max(PlayerLevels.ExpNeededPerLevel.Value, 1); expPrev = expCurrent; expCurrent = num % PlayerLevels.ExpNeededPerLevel.Value; Debug.Log((object)$"Gained {expGainedFromKills} from kills (+{levelsGainedLastRound} additional levels)"); int num2 = (RunManager.instance.levelsCompleted - 1) * PlayerLevels.NumberOfUpgradesPerLevel.Value; Dictionary<string, int> currentStats2 = GetCurrentStats(); int num3 = 0; foreach (KeyValuePair<string, int> item in currentStats2) { num3 += item.Value; } int num4 = Mathf.Max(0, num2 - num3); Debug.Log((object)$"{num4} upgrades desynched"); value += num4 + levelsGainedLastRound * PlayerLevels.NumberOfUpgradesPerLevel.Value; Dictionary<string, int> dictionary = PickRandomUpgrades(currentStats, maximumStats, value); Debug.Log((object)$"Picking {value} random upgrades"); foreach (KeyValuePair<string, int> item2 in dictionary) { if (item2.Value != 0) { Debug.Log((object)$" {item2.Key} +{item2.Value} (Max={maximumStats[item2.Key]})"); } } return ApplyUpgrades(dictionary); } private static IEnumerator DisplayExperiencedGained(List<string> appliedUpgrades) { while (!SemiFunc.RunIsLevel() || (Object)(object)GameDirector.instance == (Object)null || (int)GameDirector.instance.currentState != 2) { yield return (object)new WaitForSeconds(0.5f); } int totalExperiencedGained = PlayerLevels.GetExpGainedFromKills(); if (totalExperiencedGained > 0) { REPOPopupPage page = MenuAPI.CreateREPOPopupPage("Experience gained", (PresetSide)1, false, false, 1.5f); page.OpenPage(true); yield return (object)new WaitForSeconds(1f); int j = 0; foreach (KeyValuePair<string, int> kvp in PlayerLevels.KillCounts) { if (kvp.Value != 0) { string enemyName = kvp.Key; int kills = kvp.Value; _ = kills * PlayerLevels.GetExpForEnemyType(enemyName); float x2 = 420f + (float)j * 0f; float y3 = 270f + (float)j * -25f; string fullText = $"{enemyName} x {kills}"; page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) REPOLabel label2 = MenuAPI.CreateREPOLabel("", parent, new Vector2(x2, y3)); UpgradeCoroutineManager.Instance.AnimateText(label2, fullText); }); yield return (object)new WaitForSeconds(0.5f); j++; } } Coroutine animCoroutine = null; string fullText2 = "{0} experienced gained"; float x3 = 420f + (float)j * 0f - 20f; float y2 = 270f + (float)j * -25f - 15f; page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) REPOLabel label = MenuAPI.CreateREPOLabel("", parent, new Vector2(x3, y2)); animCoroutine = UpgradeCoroutineManager.Instance.AnimateValue(label, expPrev, expPrev + totalExperiencedGained, fullText2, 3f); }); if (animCoroutine != null) { yield return animCoroutine; j++; float x = 420f + (float)j * 0f - 20f; float y = 270f + (float)j * -25f - 15f; if (levelsGainedLastRound > 0) { page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) REPOLabel val = MenuAPI.CreateREPOLabel($"+{levelsGainedLastRound} levels", parent, new Vector2(x, y)); }); } } PlayerLevels.KillCounts.Clear(); yield return (object)new WaitForSeconds(1f); page.ClosePage(true); } yield return (object)new WaitForNextFrameUnit(); ((MonoBehaviour)UpgradeCoroutineManager.Instance).StartCoroutine(DisplayUIPopoutText(appliedUpgrades)); } private static IEnumerator DisplayUIPopoutText(List<string> upgradesReceived) { List<string> upgradesReceived2 = upgradesReceived; SemiFunc.PlayerAvatarLocal(); string message = "Upgrades received: " + string.Join(", ", upgradesReceived2); Debug.Log((object)message); REPOPopupPage page = MenuAPI.CreateREPOPopupPage("Upgrades received", (PresetSide)1, false, false, 1.5f); upgradesReceived2.Sort(); page.OpenPage(true); yield return (object)new WaitForNextFrameUnit(); for (int i = 0; i < upgradesReceived2.Count; i++) { string upgrade = upgradesReceived2[i]; float x = 420f + (float)i * 0f; float y = 270f + (float)i * -25f; float _x = x; float _y = y; page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) REPOLabel label = MenuAPI.CreateREPOLabel("", parent, new Vector2(_x, _y)); UpgradeCoroutineManager.Instance.AnimateText(label, upgrade); }); yield return (object)new WaitForSeconds(0.5f); } page.AddElement((BuilderDelegate)delegate(Transform parent) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) REPOButton val = MenuAPI.CreateREPOButton("OK", (Action)delegate { page.ClosePage(true); }, parent, new Vector2(420f + (float)upgradesReceived2.Count * 0f, 270f + (float)upgradesReceived2.Count * -25f * 1.25f)); }); } private static IEnumerator WaitPlayerReadyLevelup() { yield return (object)new WaitForEndOfFrameUnit(); canUpgrade = LevelUp(); } [HarmonyPatch("SpawnRPC")] [HarmonyPostfix] private static void SpawnRPC_Postfix(PhotonView __instance) { if (BLACK_LISTED_LEVELS.Contains(RunManager.instance.levelCurrent) || RunManager.instance.levelsCompleted == 0) { Debug.Log((object)$"Skipping level up: blackListedLevel:{BLACK_LISTED_LEVELS.Contains(RunManager.instance.levelCurrent)}, levelsCompleted:{RunManager.instance.levelsCompleted}"); canUpgrade = true; return; } if (!canUpgrade) { Debug.Log((object)$"Skipping level up: canUpgrade:{canUpgrade}"); return; } canUpgrade = false; UpgradeCoroutineManager instance = UpgradeCoroutineManager.Instance; Debug.Log((object)$"Attemtping to level up: managerInstance:{(Object)(object)instance != (Object)null}"); if ((Object)(object)instance != (Object)null) { if (instance.waitPlayerReadyCoroutine != null) { ((MonoBehaviour)instance).StopCoroutine(instance.waitPlayerReadyCoroutine); } instance.waitPlayerReadyCoroutine = ((MonoBehaviour)instance).StartCoroutine(WaitPlayerReadyLevelup()); } } } [HarmonyPatch(typeof(NetworkManager))] public static class NetworkManagerPatch { [HarmonyPatch("OnPlayerLeftRoom")] [HarmonyPrefix] public static void OnPlayerLeftRoom_Prefix(Player otherPlayer) { if (!GameManager.Multiplayer()) { Debug.Log((object)"OnPlayerLeftRoom_Prefix but we are not in multiplayer"); } else if (PlayerLevels.ShowPlayerLeaveEvents.Value) { RoundDirectorPatch.PlayerLeftNotice(otherPlayer.nickName); } } } public class UpgradeCoroutineManager : MonoBehaviour { public struct Keyframe { public Vector2 Position; public float LerpTime; public Keyframe(Vector2 position, float lerpTime) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) Position = position; LerpTime = lerpTime; } } public enum LerpType { Linear, Exponential, Easing } public Coroutine? waitPlayerReadyCoroutine = null; private static UpgradeCoroutineManager? _instance; public static UpgradeCoroutineManager Instance { get { if ((Object)(object)_instance == (Object)null) { _instance = ((Component)StatsManager.instance).GetComponent<UpgradeCoroutineManager>(); if ((Object)(object)_instance == (Object)null) { _instance = ComponentHolderProtocol.AddComponent<UpgradeCoroutineManager>((Object)(object)StatsManager.instance); } } return _instance; } } public Coroutine AnimateText(REPOLabel label, string fullText, float delayBetweenChars = 0.03f) { return ((MonoBehaviour)this).StartCoroutine(AnimateTextCoroutine(label, fullText, delayBetweenChars)); } private IEnumerator AnimateTextCoroutine(REPOLabel label, string fullText, float delayBetweenChars) { string currentText = ""; for (int i = 0; i < fullText.Length; i++) { currentText += fullText[i]; ((TMP_Text)label.labelTMP).text = currentText; yield return (object)new WaitForSeconds(delayBetweenChars); } } public Coroutine AnimateValue(REPOLabel label, int start, int end, string format, float duration = 1f, Action onComplete = null, int easingType = 1) { return ((MonoBehaviour)this).StartCoroutine(AnimateValueCoroutine(label, start, end, format, duration, onComplete, easingType)); } private IEnumerator AnimateValueCoroutine(REPOLabel label, int start, int end, string format, float duration, Action onComplete, int easingType) { float elapsed = 0f; while (elapsed < duration) { elapsed += Time.deltaTime; float normalizedTime = Mathf.Clamp01(elapsed / duration); if (easingType == 1) { normalizedTime = EaseInOut(normalizedTime); } int currentValue = (int)Mathf.Lerp((float)start, (float)end, normalizedTime); ((TMP_Text)label.labelTMP).text = string.Format(format, currentValue); yield return null; } ((TMP_Text)label.labelTMP).text = string.Format(format, end); onComplete?.Invoke(); } private float EaseInOut(float t) { return (t < 0.5f) ? (4f * t * t * t) : (1f - Mathf.Pow(-2f * t + 2f, 3f) / 2f); } public Coroutine AnimateLabel(REPOLabel label, Keyframe[] keyframes, bool hideAfterAnimationDone = false, LerpType lerpType = LerpType.Linear) { if (keyframes == null || keyframes.Length < 2) { Debug.LogError((object)"AnimateLabel requires at least 2 keyframes"); return null; } return ((MonoBehaviour)this).StartCoroutine(AnimateLabelCoroutine(label, keyframes, hideAfterAnimationDone, lerpType)); } private IEnumerator AnimateLabelCoroutine(REPOLabel label, Keyframe[] keyframes, bool hideAfterAnimationDone, LerpType lerpType) { ((Component)label).gameObject.SetActive(true); ((Transform)((REPOElement)label).rectTransform).localPosition = Vector2.op_Implicit(keyframes[0].Position); for (int i = 0; i < keyframes.Length - 1; i++) { Keyframe current = keyframes[i]; Keyframe next = keyframes[i + 1]; float duration = current.LerpTime; float elapsed = 0f; Debug.Log((object)$"Animating notification label ({i}/{keyframes.Length} keyframes)"); while (elapsed < duration && (Object)(object)label != (Object)null && (Object)(object)((REPOElement)label).rectTransform != (Object)null) { elapsed += Time.deltaTime; float normalizedTime = Mathf.Clamp01(elapsed / duration); switch (lerpType) { case LerpType.Linear: ((Transform)((REPOElement)label).rectTransform).localPosition = Vector2.op_Implicit(Vector2.Lerp(current.Position, next.Position, normalizedTime)); break; case LerpType.Exponential: { float exponentialT = normalizedTime * normalizedTime; ((Transform)((REPOElement)label).rectTransform).localPosition = Vector2.op_Implicit(Vector2.Lerp(current.Position, next.Position, exponentialT)); break; } case LerpType.Easing: { float easedT = EaseInOut(normalizedTime); ((Transform)((REPOElement)label).rectTransform).localPosition = Vector2.op_Implicit(Vector2.Lerp(current.Position, next.Position, easedT)); break; } } yield return null; } ((Transform)((REPOElement)label).rectTransform).localPosition = Vector2.op_Implicit(next.Position); } if (hideAfterAnimationDone) { ((Component)label).gameObject.SetActive(false); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerEnergy")] public static class UpgradePlayerEnergyPatch { private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerEnergyRPC", (RpcTarget)1, new object[2] { _steamID, ___statsManager.playerUpgradeStamina[_steamID] }); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerExtraJump")] public static class UpgradePlayerExtraJumpPatch { private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerExtraJumpRPC", (RpcTarget)1, new object[2] { _steamID, ___statsManager.playerUpgradeExtraJump[_steamID] }); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerGrabRange")] public static class UpgradePlayerGrabRangePatch { private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerGrabRangeRPC", (RpcTarget)1, new object[2] { _steamID, ___statsManager.playerUpgradeRange[_steamID] }); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerGrabStrength")] public static class UpgradePlayerGrabStrengthPatch { private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerGrabStrengthRPC", (RpcTarget)1, new object[2] { _steamID, ___statsManager.playerUpgradeStrength[_steamID] }); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerHealth")] public static class UpgradePlayerHealthPatch { private static void Postfix(string playerName, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerHealthRPC", (RpcTarget)1, new object[2] { playerName, ___statsManager.playerUpgradeHealth[playerName] }); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerSprintSpeed")] public static class UpgradePlayerSprintSpeedPatch { private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerSprintSpeedRPC", (RpcTarget)1, new object[2] { _steamID, ___statsManager.playerUpgradeSpeed[_steamID] }); } } } [HarmonyPatch(typeof(PunManager))] [HarmonyPatch("UpgradePlayerTumbleLaunch")] public static class UpgradePlayerTumbleLaunchPatch { private static void Postfix(string _steamID, PhotonView ___photonView, StatsManager ___statsManager) { if (!SemiFunc.IsMasterClient() && GameManager.Multiplayer()) { ___photonView.RPC("UpgradePlayerTumbleLaunchRPC", (RpcTarget)1, new object[2] { _steamID, ___statsManager.playerUpgradeLaunch[_steamID] }); } } } public static class PLAYER_STATS_ENUM { public const string HEALTH_KEY = "Health"; public const string STAMINA_KEY = "Stamina"; public const string GRAB_STRENGTH_KEY = "Strength"; public const string GRAB_RANGE_KEY = "Range"; public const string SPRINT_SPEED_KEY = "Speed"; public const string TUMBLE_LAUNCH_KEY = "Launch"; public const string EXTRA_JUMP_KEY = "Extra Jump"; } public static class ENEMY_TYPE_ENUM { public const string ANIMAL_KEY = "Animal"; public const string BANG_KEY = "Banger"; public const string BEAMER_KEY = "Clown"; public const string BOWTIE_KEY = "Bowtie"; public const string CEILING_EYE_KEY = "Peeper"; public const string DUCK_KEY = "Apex Predator"; public const string FLOATER_KEY = "Mentalist"; public const string GNOME_KEY = "Gnome"; public const string HIDDEN_KEY = "Hidden"; public const string HUNTER_KEY = "Huntsman"; public const string ROBE_KEY = "Robe"; public const string RUNNER_KEY = "Reaper"; public const string SLOW_MOUTH_KEY = "Spewer"; public const string SLOW_WALKER_KEY = "Trudge"; public const string THINMAN_KEY = "Shadow Child"; public const string TUMBLER_KEY = "Chef"; public const string UPSCREAM_KEY = "Upscream"; public const string VALUABLE_THROWER_KEY = "Rugrat"; public const string HEADMAN_KEY = "Headman"; public static string[] GetAllTypes() { return new string[19] { "Animal", "Robe", "Gnome", "Apex Predator", "Upscream", "Banger", "Clown", "Rugrat", "Huntsman", "Bowtie", "Chef", "Mentalist", "Hidden", "Reaper", "Spewer", "Trudge", "Shadow Child", "Peeper", "Headman" }; } } [HarmonyPatch(typeof(PlayerController))] public static class PlayerControllerPatch { public static float timeSinceSprintStop; public static float culmulatedHealthRegenerated; [HarmonyPostfix] [HarmonyPatch("Update")] public static void Update_Postfix(PlayerController __instance) { if (__instance.sprinting) { timeSinceSprintStop = 0f; return; } timeSinceSprintStop += Time.deltaTime; if (timeSinceSprintStop > PlayerLevels.DelayBeforeRegen.Value) { string steamID = PlayerSpawnPatch.GetSteamID(); float num = 0f; if (steamID != null && StatsManager.instance.playerUpgradeStamina.ContainsKey(steamID)) { num = StatsManager.instance.playerUpgradeStamina[steamID]; } __instance.EnergyCurrent += ((float)PlayerLevels.BaseStaminaLevel.Value + num) * Time.deltaTime * PlayerLevels.StaminaRegenPerLevel.Value; __instance.EnergyCurrent = Mathf.Clamp(__instance.EnergyCurrent, 0f, __instance.EnergyStart); int num2 = 0; if (steamID != null && StatsManager.instance.playerUpgradeHealth.ContainsKey(steamID)) { num2 = StatsManager.instance.playerUpgradeHealth[steamID]; } culmulatedHealthRegenerated += (float)(PlayerLevels.BaseHealthLevel.Value + num2) * Time.deltaTime * PlayerLevels.HealthRegenPerLevel.Value; if (culmulatedHealthRegenerated >= 1f) { __instance.playerAvatarScript.playerHealth.Heal((int)culmulatedHealthRegenerated, false); culmulatedHealthRegenerated -= (int)culmulatedHealthRegenerated; culmulatedHealthRegenerated = Mathf.Max(culmulatedHealthRegenerated, 0f); } } } } public static class Utilities { public static void DebugGameObjectHierarchy(GameObject? go, int level = 0, string indent = " ") { if (!((Object)(object)go == (Object)null)) { string text = ""; for (int i = 0; i < level; i++) { text += " "; } text += level; Debug.Log((object)(text + ": name=" + ((Object)go).name + ", tags=" + go.tag)); if ((Object)(object)go.transform.parent != (Object)null) { DebugGameObjectHierarchy(((Component)go.transform.parent).gameObject, level + 1); } } } } [HarmonyPatch(typeof(HurtCollider))] public static class HurtColliderPatch { private static int CalculateTubleDamage(int tumbleLevel) { return tumbleLevel switch { 0 => 15, 1 => PlayerLevels.TumbleLevel1Damage.Value, 2 => PlayerLevels.TumbleLevel2Damage.Value, 3 => PlayerLevels.TumbleLevel3Damage.Value, 4 => PlayerLevels.TumbleLevel4Damage.Value, _ => PlayerLevels.TumbleLevel4Damage.Value + PlayerLevels.TumbleLevelNDamage.Value * (tumbleLevel - 4), }; } [HarmonyPatch("EnemyHurt")] [HarmonyPrefix] public static void EnemyHurt_Prefix(HurtCollider __instance) { PlayerTumble componentInParent = ((Component)__instance).GetComponentInParent<PlayerTumble>(); if ((Object)(object)componentInParent != (Object)null && __instance.enemyDamage > 0) { Dictionary<string, int> currentStats = PlayerSpawnPatch.GetCurrentStats(); if (currentStats == null) { Debug.Log((object)"Unable to get player stats"); return; } int tumbleLevel = currentStats["Launch"]; __instance.enemyDamage = CalculateTubleDamage(tumbleLevel); } } [HarmonyPatch("EnemyHurt")] [HarmonyPostfix] public static void EnemyHurt_Postfix(HurtCollider __instance) { PlayerTumble componentInParent = ((Component)__instance).GetComponentInParent<PlayerTumble>(); if ((Object)(object)componentInParent != (Object)null && __instance.enemyDamage > 0) { __instance.enemyDamage = 15; } } } [HarmonyPatch(typeof(EnemyHealth))] internal static class EnemyHealthPatch { [HarmonyPatch("Death")] [HarmonyPrefix] public static void Death_Prefix(EnemyHealth __instance) { string text = __instance.enemy.EnemyParent.enemyName; if (text == null) { Debug.LogWarning((object)"EnemyHealth instance does not have a valid enemyName"); text = "???"; } if (!PlayerLevels.KillCounts.ContainsKey(text)) { PlayerLevels.KillCounts[text] = 0; } PlayerLevels.KillCounts[text]++; Debug.Log((object)("Killed " + text)); } } [HarmonyPatch(typeof(RoundDirector))] public static class RoundDirectorPatch { public static Transform? gameHUD; public static REPOLabel? noticeLabel; public static Vector2 LABEL_VISIBLE_POSITION = new Vector2(146f, -140f); public static Vector2 LABEL_OFFSCREEN_POSITION = new Vector2(146f, -2000f); public static Coroutine? playerLeaveNotificationCoroutine; public static Queue<string> playerLeaveQueue = new Queue<string>(); public static bool isProcessingQueue = false; public static bool TryGetNotificationLabel() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.Find("Game Hud"); if ((Object)(object)gameHUD == (Object)null) { Debug.Log((object)"Searching for 'Game Hud' game object"); gameHUD = ((val != null) ? val.transform : null); } if ((Object)(object)gameHUD != (Object)null && (Object)(object)noticeLabel == (Object)null) { Debug.Log((object)"gameHUD found! Creating notification label"); noticeLabel = MenuAPI.CreateREPOLabel("", gameHUD, LABEL_OFFSCREEN_POSITION); ((Component)noticeLabel).gameObject.SetActive(false); } return (Object)(object)gameHUD != (Object)null && (Object)(object)noticeLabel != (Object)null; } [HarmonyPatch(typeof(LoadingUI), "StopLoading")] [HarmonyPostfix] public static void StopLoading_Postfix(LoadingUI __instance) { Debug.Log((object)"Resetting notification label"); TryGetNotificationLabel(); playerLeaveQueue.Clear(); isProcessingQueue = false; if (playerLeaveNotificationCoroutine != null) { Debug.Log((object)"Stopping player notification coroutine"); ((MonoBehaviour)UpgradeCoroutineManager.Instance).StopCoroutine(playerLeaveNotificationCoroutine); } } public static void UpdateNoticeLabel(string text) { if (!TryGetNotificationLabel()) { Debug.LogWarning((object)"No Game HUD or Label found"); } else { ((TMP_Text)noticeLabel.labelTMP).text = text; } } public static void ToggleNoticeLabelVisibility(bool visible) { if (!TryGetNotificationLabel()) { Debug.LogWarning((object)"No Label found"); } else { ((Component)noticeLabel).gameObject.SetActive(visible); } } public static void PlayerLeftNotice(string playerName) { playerLeaveQueue.Enqueue(playerName); Debug.Log((object)"Queued player leave event!"); if (!isProcessingQueue) { Debug.Log((object)"Starting notification coroutine"); isProcessingQueue = true; playerLeaveNotificationCoroutine = ((MonoBehaviour)UpgradeCoroutineManager.Instance).StartCoroutine(ProcessPlayerLeaveQueue()); } } private static IEnumerator ProcessPlayerLeaveQueue() { while (playerLeaveQueue.Count > 0) { string playerName = playerLeaveQueue.Dequeue(); string msg = playerName + "\nHas left!"; Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom != null) { msg += $"\n({currentRoom.PlayerCount} remaining)"; } Debug.Log((object)("Processing player " + playerName + " leave event notification")); UpdateNoticeLabel(msg); ToggleNoticeLabelVisibility(visible: true); if ((Object)(object)noticeLabel == (Object)null) { TryGetNotificationLabel(); if ((Object)(object)noticeLabel == (Object)null) { Debug.LogError((object)"Could not process playerLeave notification because the label could not be created"); playerLeaveQueue.Clear(); break; } } ((Transform)((REPOElement)noticeLabel).rectTransform).localPosition = Vector2.op_Implicit(LABEL_OFFSCREEN_POSITION); UpgradeCoroutineManager.Keyframe[] keyframes = new UpgradeCoroutineManager.Keyframe[4] { new UpgradeCoroutineManager.Keyframe(LABEL_OFFSCREEN_POSITION, 2f), new UpgradeCoroutineManager.Keyframe(LABEL_VISIBLE_POSITION, 5f), new UpgradeCoroutineManager.Keyframe(LABEL_VISIBLE_POSITION, 2f), new UpgradeCoroutineManager.Keyframe(LABEL_OFFSCREEN_POSITION, 1f) }; yield return UpgradeCoroutineManager.Instance.AnimateLabel(noticeLabel, keyframes, hideAfterAnimationDone: true); } yield return (object)new WaitForSeconds(0.5f); isProcessingQueue = false; } } }