using 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;
}
}
}