Decompiled source of LethalStatsLC v2.0.1

OrianaGames-Stats/LethalProgression.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Inputs;
using LethalCompanyInputUtils.Api;
using LethalNetworkAPI;
using LethalProgression;
using LethalProgression.Config;
using LethalProgression.GUI;
using LethalProgression.Network;
using LethalProgression.Patches;
using LethalProgression.Properties;
using LethalProgression.Saving;
using LethalProgression.Skills;
using LethalProgression.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using NightVision.Patches;
using Steamworks;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.UI;

[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: AssemblyCompany("LethalProgression")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Lethal Progression FR Version Orianagames")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0-alpha.0")]
[assembly: AssemblyProduct("LethalProgression")]
[assembly: AssemblyTitle("LethalProgression")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class LC_XP_WisdomHandler : MonoBehaviour
{
	private PlayerControllerB player;

	private float previousWisdom = -1f;

	private void Start()
	{
		player = ((Component)this).GetComponent<PlayerControllerB>();
	}

	private void Update()
	{
		if (!NetworkManager.Singleton.IsServer || (Object)(object)player == (Object)null || player.playerClientId != NetworkManager.Singleton.LocalClientId)
		{
			return;
		}
		float num = 0f;
		if ((Object)(object)LP_NetworkManager.xpInstance != (Object)null && LP_NetworkManager.xpInstance.skillList != null && LP_NetworkManager.xpInstance.skillList.skills.ContainsKey(UpgradeType.Wisdom))
		{
			num = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Wisdom].GetTrueValue();
		}
		if (Mathf.Abs(num - previousWisdom) > 0.01f)
		{
			previousWisdom = num;
			if ((Object)(object)LP_NetworkManager.xpWisdomInstance != (Object)null)
			{
				LP_NetworkManager.xpWisdomInstance.SetWisdomLevel((int)player.playerClientId, num);
				Debug.Log((object)$"[WisdomSync] Updated Wisdom for player {player.playerClientId} → {num:F2}");
			}
		}
	}
}
public class WAV
{
	public float[] LeftChannel;

	public int ChannelCount;

	public int SampleCount;

	public int Frequency;

	public WAV(byte[] wav)
	{
		ChannelCount = wav[22];
		Frequency = BytesToInt(wav, 24);
		int i;
		for (i = 12; wav[i] != 100 || wav[i + 1] != 97 || wav[i + 2] != 116 || wav[i + 3] != 97; i += 4)
		{
		}
		i += 8;
		SampleCount = (wav.Length - i) / 2;
		LeftChannel = new float[SampleCount];
		int num = 0;
		while (i < wav.Length)
		{
			short num2 = (short)((wav[i + 1] << 8) | wav[i]);
			LeftChannel[num] = (float)num2 / 32768f;
			i += 2;
			num++;
		}
	}

	private int BytesToInt(byte[] bytes, int offset)
	{
		return (bytes[offset + 3] << 24) | (bytes[offset + 2] << 16) | (bytes[offset + 1] << 8) | bytes[offset];
	}
}
namespace NightVision
{
	public static class NightVisionAudioLoader
	{
		public static AudioClip LoadWav(string name)
		{
			string text = Path.Combine(Paths.PluginPath, "OrianaGames-LethalStatsLC", name + ".wav");
			if (!File.Exists(text))
			{
				Debug.LogWarning((object)("[NightVision] File not found: " + text));
				return null;
			}
			try
			{
				byte[] wav = File.ReadAllBytes(text);
				WAV wAV = new WAV(wav);
				AudioClip val = AudioClip.Create(name, wAV.SampleCount, 1, wAV.Frequency, false);
				val.SetData(wAV.LeftChannel, 0);
				return val;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NightVision] Failed to load WAV: " + ex.Message));
				return null;
			}
		}
	}
	public class NightVisionAudioManager : MonoBehaviour
	{
		public static NightVisionAudioManager Instance;

		private AudioSource source;

		private AudioClip clipOn;

		private AudioClip clipOff;

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Debug.Log((object)"[NightVision] AudioManager Awake");
			source = ((Component)this).gameObject.AddComponent<AudioSource>();
			source.playOnAwake = false;
			source.volume = 1f;
			ReloadAudio();
		}

		public void ReloadAudio()
		{
			Debug.Log((object)"[NightVision] Reloading audio clips...");
			string path = Path.Combine(Paths.PluginPath, "OrianaGames-LethalStatsLC", "");
			string path2 = Path.Combine(path, "nightvision_on.wav");
			string path3 = Path.Combine(path, "nightvision_off.wav");
			if (!File.Exists(path2))
			{
				Debug.LogError((object)"[NightVision] nightvision_on.wav NOT FOUND");
			}
			if (!File.Exists(path3))
			{
				Debug.LogError((object)"[NightVision] nightvision_off.wav NOT FOUND");
			}
			clipOn = NightVisionAudioLoader.LoadWav("nightvision_on");
			clipOff = NightVisionAudioLoader.LoadWav("nightvision_off");
			Debug.Log((object)("[NightVision] clipOn loaded: " + (((Object)(object)clipOn != (Object)null) ? "✅ OK" : "❌ NULL")));
			Debug.Log((object)("[NightVision] clipOff loaded: " + (((Object)(object)clipOff != (Object)null) ? "✅ OK" : "❌ NULL")));
		}

		public void PlayToggle(bool isOn)
		{
			if ((Object)(object)clipOn == (Object)null || (Object)(object)clipOff == (Object)null)
			{
				Debug.LogWarning((object)"[NightVision] Clips were null at toggle — reloading...");
				ReloadAudio();
			}
			AudioClip val = (isOn ? clipOn : clipOff);
			if ((Object)(object)source != (Object)null && (Object)(object)val != (Object)null)
			{
				source.PlayOneShot(val);
				Debug.Log((object)"[NightVision] Playing toggle sound.");
			}
			else
			{
				Debug.LogWarning((object)"[NightVision] Cannot play toggle sound — source or clip missing.");
			}
		}
	}
}
namespace NightVision.Patches
{
	[HarmonyPatch]
	public static class Nightvision
	{
		public static void NightvisionUpdate(int updatedValue)
		{
			if (!LP_NetworkManager.xpInstance.skillList.IsSkillListValid() || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Nightvision))
			{
				return;
			}
			Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Nightvision];
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			float trueValue = skill.GetTrueValue();
			if (bool.Parse(SkillConfig.hostConfig["Special Ability: Nightvision / Capacité spécial : Vision nocturne"]))
			{
				if (int.Parse(SkillConfig.hostConfig["Nightvision Level required / Vision nocturne niveau requis"]) == 0)
				{
					PlayerControllerBPatch.NightvisionUnlocked = true;
				}
				else if (trueValue >= (float)int.Parse(SkillConfig.hostConfig["Nightvision Level required / Vision nocturne niveau requis"]))
				{
					PlayerControllerBPatch.NightvisionUnlocked = true;
				}
				else
				{
					PlayerControllerBPatch.NightvisionUnlocked = false;
				}
			}
			else
			{
				PlayerControllerBPatch.NightvisionUnlocked = false;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "Update")]
	internal class PlayerControllerBPatch
	{
		public static bool NightvisionEnable = false;

		public static float NightvisionDuration = 50f;

		public static float NightvisionCharge = 100f;

		public static float NightvisionSpeed = 0.35f;

		public static bool canToggleNightvision = true;

		public static float lastLoggedCharge = -1f;

		private static bool lastNightVisionState;

		public static bool hasCreateAudio = false;

		public static bool hasLoadedAudio = false;

		public static bool batteryVisualAttached = false;

		public static bool NightvisionUnlocked = false;

		[HarmonyPostfix]
		private static void UpdatePostfix(PlayerControllerB __instance)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			if (StartOfRound.Instance.inShipPhase)
			{
				NightvisionEnable = false;
			}
			if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)
			{
				NightvisionCharge = 100f;
			}
			if (GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				NightvisionSpeed = 0.125f;
			}
			else
			{
				NightvisionSpeed = 0.32f;
			}
			if (!NightvisionUnlocked)
			{
				NightvisionEnable = false;
			}
			if (!hasCreateAudio)
			{
				GameObject val = new GameObject("NightVisionAudioManager");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<NightVisionAudioManager>();
				hasCreateAudio = true;
			}
			if (LethalPlugin.Input.Nightvision.triggered)
			{
				if (!hasLoadedAudio && (Object)(object)NightVisionAudioManager.Instance != (Object)null)
				{
					NightVisionAudioManager.Instance.ReloadAudio();
					hasLoadedAudio = true;
				}
				if (canToggleNightvision)
				{
					canToggleNightvision = false;
					if (NightvisionEnable)
					{
						if (!NightvisionUnlocked)
						{
							NightvisionEnable = false;
							LethalPlugin.Log.LogInfo((object)"\ud83d\udd34 Nightvision locked!");
						}
						else
						{
							NightvisionEnable = false;
							LethalPlugin.Log.LogInfo((object)"\ud83d\udd34 Nightvision manually disabled.");
						}
					}
					else if (NightvisionCharge < 15f)
					{
						LethalPlugin.Log.LogInfo((object)"❌ Nightvision use blocked: battery too low (<15%).");
						NightVisionAudioManager.Instance?.PlayToggle(isOn: false);
					}
					else if (NightvisionUnlocked && !StartOfRound.Instance.inShipPhase)
					{
						NightvisionEnable = true;
						if (NightvisionCharge > 99f)
						{
							NightvisionCharge -= 1f;
						}
						else
						{
							NightvisionCharge -= 5f;
						}
						NightvisionCharge = Mathf.Max(NightvisionCharge, 0f);
					}
				}
			}
			else
			{
				canToggleNightvision = true;
			}
			if (NightvisionEnable)
			{
				NightvisionCharge -= Time.deltaTime * (100f / NightvisionDuration);
				NightvisionCharge = Mathf.Max(NightvisionCharge, 0f);
				if (NightvisionCharge <= 0f)
				{
					NightvisionEnable = false;
					LethalPlugin.Log.LogInfo((object)"Nightvision auto-disabled (Battery empty)");
				}
			}
			else if (NightvisionCharge < 100f)
			{
				NightvisionCharge += Time.deltaTime * NightvisionSpeed;
				NightvisionCharge = Mathf.Min(NightvisionCharge, 100f);
			}
			if (NightvisionEnable != lastNightVisionState && NightvisionUnlocked)
			{
				lastNightVisionState = NightvisionEnable;
				NightVisionPatch.ApplyNightVisionEffect(__instance);
				if (!StartOfRound.Instance.inShipPhase)
				{
					NightVisionAudioManager.Instance?.PlayToggle(NightvisionEnable);
				}
				NightvisionDuration = Vision.visiondurationvalue;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB), "SetNightVisionEnabled")]
	internal class NightVisionPatch
	{
		private struct LightState
		{
			public float intensity;

			public float range;

			public float shadowStrength;

			public int shadows;

			public int shape;

			public Color color;
		}

		private static LightState? savedLightState;

		[HarmonyPrefix]
		private static void NightVisionPrefix(PlayerControllerB __instance)
		{
			ApplyNightVisionEffect(__instance);
		}

		public static void ApplyNightVisionEffect(PlayerControllerB player)
		{
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected I4, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected I4, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)player.nightVision == (Object)null)
			{
				return;
			}
			if (PlayerControllerBPatch.NightvisionEnable)
			{
				if (!savedLightState.HasValue)
				{
					LightState value = default(LightState);
					value.intensity = player.nightVision.intensity;
					value.range = player.nightVision.range;
					value.shadowStrength = player.nightVision.shadowStrength;
					value.shadows = (int)player.nightVision.shadows;
					value.shape = (int)player.nightVision.shape;
					value.color = player.nightVision.color;
					savedLightState = value;
				}
				player.nightVision.intensity = 7500f;
				player.nightVision.range = 100000f;
				player.nightVision.shadowStrength = 0f;
				player.nightVision.shadows = (LightShadows)0;
				player.nightVision.shape = (LightShape)2;
				player.nightVision.color = Color.green;
			}
			else if (savedLightState.HasValue)
			{
				LightState value2 = savedLightState.Value;
				player.nightVision.intensity = value2.intensity;
				player.nightVision.range = value2.range;
				player.nightVision.shadowStrength = value2.shadowStrength;
				player.nightVision.shadows = (LightShadows)value2.shadows;
				player.nightVision.shape = (LightShape)value2.shape;
				player.nightVision.color = value2.color;
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay), "SetInsideLightingDimness")]
	internal static class NightVisionOutdoors
	{
		private struct OutdoorLightState
		{
			public float lightDimmer;

			public float intensity;

			public float shadowDimmer;

			public float shadowRadius;

			public bool useRayTracedShadows;

			public Color color;
		}

		private static OutdoorLightState? saved;

		private static float sigmoid(float x, float midpoint, float steepness)
		{
			return 1f / (1f + Mathf.Exp((0f - steepness) * (x - midpoint)));
		}

		[HarmonyPostfix]
		private static void InsideLightingPostfix(TimeOfDay __instance)
		{
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			HDAdditionalLightData component = ((Component)__instance.sunIndirect).GetComponent<HDAdditionalLightData>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			if (PlayerControllerBPatch.NightvisionEnable)
			{
				if (!saved.HasValue)
				{
					OutdoorLightState value = default(OutdoorLightState);
					value.lightDimmer = component.lightDimmer;
					value.intensity = component.intensity;
					value.shadowDimmer = component.shadowDimmer;
					value.shadowRadius = component.lightShadowRadius;
					value.useRayTracedShadows = component.useRayTracedShadows;
					value.color = component.color;
					saved = value;
				}
				float num = 10f;
				float num2 = sigmoid(__instance.globalTime, 950f, 0.1f);
				component.lightDimmer = Mathf.Lerp(10f * num, 10000f * num, num2);
				component.intensity = Mathf.Lerp(num, 1000f * num, num2);
				component.shadowDimmer = 0f;
				component.useRayTracedShadows = true;
				component.lightShadowRadius = 0f;
				component.color = Color.green;
			}
			else if (saved.HasValue)
			{
				OutdoorLightState value2 = saved.Value;
				component.lightDimmer = Mathf.Lerp(component.lightDimmer, value2.lightDimmer, 5f * Time.deltaTime);
				component.intensity = Mathf.Lerp(component.intensity, value2.intensity, 5f * Time.deltaTime);
				component.shadowDimmer = value2.shadowDimmer;
				component.useRayTracedShadows = value2.useRayTracedShadows;
				component.lightShadowRadius = value2.shadowRadius;
				component.color = value2.color;
			}
		}
	}
}
namespace Inputs
{
	public class PluginInput : LcInputActions
	{
		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction DoubleJump { get; set; }

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction Nightvision { get; set; }
	}
}
namespace LethalProgression
{
	[HarmonyPatch]
	internal class LP_NetworkManager
	{
		public static LC_XP xpInstance;

		public static LC_XP_Wisdom xpWisdomInstance;

		public static GameObject xpNetworkObject;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void Init()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (!((Object)(object)xpNetworkObject != (Object)null))
			{
				xpNetworkObject = (GameObject)LethalPlugin.skillBundle.LoadAsset("LP_XPHandler");
				if ((Object)(object)xpNetworkObject.GetComponent<LC_XP>() == (Object)null)
				{
					xpNetworkObject.AddComponent<LC_XP>();
				}
				if ((Object)(object)xpNetworkObject.GetComponent<LC_XP_Wisdom>() == (Object)null)
				{
					xpNetworkObject.AddComponent<LC_XP_Wisdom>();
				}
				NetworkManager.Singleton.AddNetworkPrefab(xpNetworkObject);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		private static void SpawnNetworkHandler()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				GameObject val = Object.Instantiate<GameObject>(xpNetworkObject, Vector3.zero, Quaternion.identity);
				val.GetComponent<NetworkObject>().Spawn(false);
				xpInstance = val.GetComponent<LC_XP>();
				xpWisdomInstance = val.GetComponent<LC_XP_Wisdom>();
				LethalPlugin.Log.LogInfo((object)"✅ XPHandler & WisdomHandler Initialized.");
			}
		}
	}
	public class LC_XP_Wisdom : NetworkBehaviour
	{
		public Dictionary<int, float> wisdomByPlayerId = new Dictionary<int, float>();

		public override void OnNetworkSpawn()
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			LethalPlugin.Log.LogInfo((object)"[Wisdom] OnNetworkSpawn - Initializing wisdom dictionary for connected players");
			foreach (NetworkClient connectedClients in NetworkManager.Singleton.ConnectedClientsList)
			{
				int num = (int)connectedClients.ClientId;
				if (!wisdomByPlayerId.ContainsKey(num))
				{
					wisdomByPlayerId[num] = 0f;
					LethalPlugin.Log.LogInfo((object)$"[Wisdom] Added player ID {num} to wisdom dictionary with value 0");
				}
				else
				{
					LethalPlugin.Log.LogInfo((object)$"[Wisdom] Player ID {num} already exists in wisdom dictionary with value {wisdomByPlayerId[num]}");
				}
			}
			LogAllWisdomValues("After OnNetworkSpawn");
		}

		public float GetWisdomLevel(int playerId)
		{
			float value;
			bool flag = wisdomByPlayerId.TryGetValue(playerId, out value);
			LethalPlugin.Log.LogInfo((object)$"[Wisdom] GetWisdomLevel requested for Player ID {playerId}: exists={flag}, value={value}");
			return flag ? value : 0f;
		}

		public void SetWisdomLevel(int playerId, float trueValue)
		{
			LethalPlugin.Log.LogInfo((object)$"[Wisdom] Setting wisdom for Player ID {playerId} to {trueValue}");
			wisdomByPlayerId[playerId] = trueValue;
		}

		public void LogAllWisdomValues(string context = "")
		{
			if (!((NetworkBehaviour)this).IsServer)
			{
				return;
			}
			LethalPlugin.Log.LogInfo((object)("[Wisdom] " + context + " - Current wisdom values for all players:"));
			foreach (KeyValuePair<int, float> item in wisdomByPlayerId)
			{
				string arg = "Unknown";
				if ((Object)(object)StartOfRound.Instance != (Object)null && item.Key >= 0 && item.Key < StartOfRound.Instance.allPlayerScripts.Length)
				{
					PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[item.Key];
					if ((Object)(object)val != (Object)null)
					{
						arg = val.playerUsername;
					}
				}
				LethalPlugin.Log.LogInfo((object)$"[Wisdom] Player ID {item.Key} ({arg}): {item.Value}");
			}
		}
	}
	[BepInPlugin("OrianaGames.LethalStats", "LethalStats", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class LethalPlugin : BaseUnityPlugin
	{
		private const string modGUID = "OrianaGames.LethalStatsLC";

		private const string modName = "LethalStats";

		private const string modVersion = "1.5.0";

		private const string modAuthor = "Lunastellia";

		public static AssetBundle skillBundle;

		public static AssetBundle UIBundle;

		public static AssetBundle RadarUIBundle;

		internal static ManualLogSource Log;

		internal static bool ReservedSlots;

		internal static bool MikesTweaks;

		public static PluginInput Input { get; private set; }

		public static LethalPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			Instance = this;
			Input = new PluginInput();
			Harmony val = new Harmony("OrianaGames.LethalStatsLC");
			val.PatchAll();
			val.PatchAll(typeof(JumpForcePatch));
			skillBundle = AssetBundle.LoadFromMemory(Resources.skillmenu);
			UIBundle = AssetBundle.LoadFromMemory(Resources.nightvision_ui);
			RadarUIBundle = AssetBundle.LoadFromMemory(Resources.radarui);
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"LethalStats loaded.");
			string value = ((BaseUnityPlugin)this).Config.Bind<string>("MONSTRES-EXP", "MonsterXPOverrides", "Hoarderbug@15;BaboonHawkEnemy@30;MouthDog@80;Centipede@15;Flowerman@200;SandSpider@60;Crawler@75;MaskedPlayerEnemy@40;ButlerEnemy@70;ForestGiant@250;Nutcracker@150;FlowerSnakeEnemy@10;Maneater@40;CaveDwellerEnemy@40;SpringMan@0;DoublewingedBird@5;PufferEnemy@0;BushWolf@50;Blob@0;Peeper@5", "EN - Optional override for all monster EXP using format: MonsterName@XP;MonsterName2@XP2...\nFR - Remplacement facultatif de tous les EXP monstres au format: Monstre@XP;Monstre2@XP2...").Value;
			EnemyBlinkingLight.LoadEnemyLightConfigsFromString("Centiped:255,0,0:25:5:0.3f;MouthDog:255,0,0:100:10:0.3f;Flowerman:255,0,0:25:5:0.3f;SandSpider:255,255,0:25:2:0.3f;Crawler:255,0,0:10:3:0.6f;ForestGiant:255,0,0:100:15:0.5f;CaveDwellerEnemy:255,0,0:25:5:0.5f;Peeper:255,0,255:10:1:0.3f;");
			EnemyAIPatch.LoadEnemyRewardsFromString(value);
			ReservedSlots = false;
			MikesTweaks = false;
			Log.LogInfo((object)"Début de la détection des mods de slots...");
			Log.LogInfo((object)"ReservedItemSlotCore non détecté par GUID. Vérification d'autres mods...");
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				string gUID = pluginInfo.Value.Metadata.GUID;
				if (gUID.ToLowerInvariant().Contains("reserveditem"))
				{
					Log.LogInfo((object)("Détection d'un mod contenant 'ReservedItem': " + gUID + ". HandSlots sera désactivé."));
					ReservedSlots = true;
				}
				if (!gUID.ToLowerInvariant().Contains("mikestweaks"))
				{
					continue;
				}
				Log.LogInfo((object)"MikesTweaks détecté.");
				MikesTweaks = true;
				try
				{
					ConfigEntryBase[] configEntries = pluginInfo.Value.Instance.Config.GetConfigEntries();
					ConfigEntryBase[] array = configEntries;
					foreach (ConfigEntryBase val2 in array)
					{
						if (val2.Definition.Key == "ExtraItemSlots" && int.Parse(val2.GetSerializedValue()) > 0)
						{
							Log.LogInfo((object)"MikesTweaks ajoute des slots. HandSlots sera désactivé.");
							ReservedSlots = true;
						}
					}
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Erreur lors de la lecture de la config de MikesTweaks: " + ex.Message));
				}
			}
			if (ReservedSlots)
			{
				Log.LogWarning((object)"Résultat détection: Le flag 'ReservedSlots' est TRUE (par un autre mod que le Core API). La compétence HandSlots sera désactivée.");
			}
			else
			{
				Log.LogInfo((object)"Résultat détection: Aucun mod de slot conflictuel détecté. La compétence HandSlots devrait être active.");
			}
			SkillConfig.InitConfig();
		}

		public void BindConfig<T>(string section, string key, T defaultValue, string description = "")
		{
			((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description);
		}

		public IDictionary<string, string> GetAllConfigEntries()
		{
			return ((BaseUnityPlugin)this).Config.GetConfigEntries().ToDictionary((ConfigEntryBase entry) => entry.Definition.Key, (ConfigEntryBase entry) => entry.GetSerializedValue());
		}
	}
	internal class LC_XP : NetworkBehaviour
	{
		public LethalNetworkVariable<int> teamLevel = new LethalNetworkVariable<int>("teamLevel")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamXP = new LethalNetworkVariable<int>("teamXP")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamTotalValue = new LethalNetworkVariable<int>("teamTotalValue")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamXPRequired = new LethalNetworkVariable<int>("teamXPRequired")
		{
			Value = 0
		};

		public LethalNetworkVariable<int> teamLootLevel = new LethalNetworkVariable<int>("teamLootLevel")
		{
			Value = 0
		};

		public LethalClientEvent playerConnectClientEvent = new LethalClientEvent("playerConnectEvent", (Action)null, (Action<ulong>)null);

		public LethalServerEvent playerConnectServerEvent = new LethalServerEvent("playerConnectEvent", (Action<ulong>)null);

		public LethalClientEvent evaluateXPRequirementClientEvent = new LethalClientEvent("evaluateXPRequirementEvent", (Action)null, (Action<ulong>)null);

		public LethalServerEvent evaluateXPRequirementServerEvent = new LethalServerEvent("evaluateXPRequirementEvent", (Action<ulong>)null);

		public LethalClientEvent calculateAllPlayersHandSlotsClientEvent = new LethalClientEvent("calculateAllPlayersHandSlotsEvent", (Action)null, (Action<ulong>)null);

		public LethalServerEvent calculateAllPlayersHandSlotsServerEvent = new LethalServerEvent("calculateAllPlayersHandSlotsEvent", (Action<ulong>)null);

		public LethalServerMessage<string> sendConfigServerMessage = new LethalServerMessage<string>("sendConfigMessage", (Action<string, ulong>)null);

		public LethalClientMessage<string> sendConfigClientMessage = new LethalClientMessage<string>("sendConfigMessage", (Action<string>)null, (Action<string, ulong>)null);

		public LethalServerMessage<ulong> requestProfileDataServerMessage = new LethalServerMessage<ulong>("requestProfileDataMessage", (Action<ulong, ulong>)null);

		public LethalClientMessage<ulong> requestProfileDataClientMessage = new LethalClientMessage<ulong>("requestProfileDataMessage", (Action<ulong>)null, (Action<ulong, ulong>)null);

		public LethalServerMessage<string> sendProfileDataServerMessage = new LethalServerMessage<string>("sendProfileDataMessage", (Action<string, ulong>)null);

		public LethalClientMessage<string> receiveProfileDataClientMessage = new LethalClientMessage<string>("sendProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null);

		public LethalServerMessage<string> saveProfileDataServerMessage = new LethalServerMessage<string>("saveProfileDataMessage", (Action<string, ulong>)null);

		public LethalClientMessage<string> saveProfileDataClientMessage = new LethalClientMessage<string>("saveProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null);

		public LethalServerMessage<int> updateTeamLootLevelServerMessage = new LethalServerMessage<int>("updateTeamLootLevelMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updateTeamLootLevelClientMessage = new LethalClientMessage<int>("updateTeamLootLevelMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<int> updateTeamXPServerMessage = new LethalServerMessage<int>("updateTeamXPMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updateTeamXPClientMessage = new LethalClientMessage<int>("updateTeamXPMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<int> updatePlayerSkillpointsServerMessage = new LethalServerMessage<int>("updatePlayerSkillPointsMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updatePlayerSkillpointsClientMessage = new LethalClientMessage<int>("updatePlayerSkillPointsMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<int> updateSPHandSlotsServerMessage = new LethalServerMessage<int>("updateSPHandSlotsMessage", (Action<int, ulong>)null);

		public LethalClientMessage<int> updateSPHandSlotsClientMessage = new LethalClientMessage<int>("updateSPHandSlotsMessage", (Action<int>)null, (Action<int, ulong>)null);

		public LethalServerMessage<PlayerHandSlotData> updatePlayerHandSlotsServerMessage = new LethalServerMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData, ulong>)null);

		public LethalClientMessage<PlayerHandSlotData> updatePlayerHandSlotsClientMessage = new LethalClientMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData>)null, (Action<PlayerHandSlotData, ulong>)null);

		public LethalServerMessage<PlayerJumpHeightData> updatePlayerJumpForceServerMessage = new LethalServerMessage<PlayerJumpHeightData>("updatePlayerJumpForceMessage", (Action<PlayerJumpHeightData, ulong>)null);

		public LethalClientMessage<PlayerJumpHeightData> updatePlayerJumpForceClientMessage = new LethalClientMessage<PlayerJumpHeightData>("updatePlayerJumpForceMessage", (Action<PlayerJumpHeightData>)null, (Action<PlayerJumpHeightData, ulong>)null);

		public int skillPoints;

		public SkillList skillList;

		public SkillsGUI guiObj;

		public bool Initialized = false;

		public bool loadedSave = false;

		public void Start()
		{
			LethalPlugin.Log.LogInfo((object)"XP Network Behavior Made!");
			teamLevel.OnValueChanged += OnTeamLevelChange;
			teamXP.OnValueChanged += OnTeamXPChange;
			playerConnectServerEvent.OnReceived += PlayerConnect_C2SEvent;
			evaluateXPRequirementServerEvent.OnReceived += EvaluateXPRequirements_C2SEvent;
			calculateAllPlayersHandSlotsServerEvent.OnReceived += RefreshAllPlayerHandSlots_C2SEvent;
			requestProfileDataServerMessage.OnReceived += RequestSavedData_C2SMessage;
			saveProfileDataServerMessage.OnReceived += SaveProfileData_C2SMessage;
			updateTeamLootLevelServerMessage.OnReceived += UpdateTeamLootLevel_C2SMessage;
			updateTeamXPServerMessage.OnReceived += UpdateTeamXP_C2SMessage;
			updateSPHandSlotsServerMessage.OnReceived += UpdateSPHandSlots_C2SMessage;
			updatePlayerJumpForceServerMessage.OnReceived += UpdatePlayerJumpHeight_C2SMessage;
			sendConfigClientMessage.OnReceived += SendHostConfig_S2CMessage;
			receiveProfileDataClientMessage.OnReceived += LoadProfileData_S2CMessage;
			updatePlayerSkillpointsClientMessage.OnReceived += UpdateSkillPoints_S2CMessage;
			updatePlayerHandSlotsClientMessage.OnReceived += UpdatePlayerHandSlots_S2CMessage;
			updatePlayerJumpForceClientMessage.OnReceived += UpdatePlayerJumpHeight_S2CMessage;
			playerConnectClientEvent.InvokeServer();
		}

		public override void OnDestroy()
		{
			teamLevel.OnValueChanged -= OnTeamLevelChange;
			teamXP.OnValueChanged -= OnTeamXPChange;
			teamLootLevel.OnValueChanged -= guiObj.TeamLootHudUpdate;
			playerConnectServerEvent.OnReceived -= PlayerConnect_C2SEvent;
			evaluateXPRequirementServerEvent.OnReceived -= EvaluateXPRequirements_C2SEvent;
			calculateAllPlayersHandSlotsServerEvent.OnReceived -= RefreshAllPlayerHandSlots_C2SEvent;
			requestProfileDataServerMessage.OnReceived -= RequestSavedData_C2SMessage;
			saveProfileDataServerMessage.OnReceived -= SaveProfileData_C2SMessage;
			updateTeamLootLevelServerMessage.OnReceived -= UpdateTeamLootLevel_C2SMessage;
			updateTeamXPServerMessage.OnReceived -= UpdateTeamXP_C2SMessage;
			updateSPHandSlotsServerMessage.OnReceived -= UpdateSPHandSlots_C2SMessage;
			sendConfigClientMessage.OnReceived -= SendHostConfig_S2CMessage;
			receiveProfileDataClientMessage.OnReceived -= LoadProfileData_S2CMessage;
			updatePlayerSkillpointsClientMessage.OnReceived -= UpdateSkillPoints_S2CMessage;
			updatePlayerHandSlotsClientMessage.OnReceived -= UpdatePlayerHandSlots_S2CMessage;
			((NetworkBehaviour)this).OnDestroy();
		}

		private void OnTeamLevelChange(int newLevel)
		{
			((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowLevelUp));
		}

		private void OnTeamXPChange(int newXP)
		{
			((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowXPUpdate));
		}

		public IEnumerator WaitUntilInitialisedThenAction(Action callback)
		{
			yield return (object)new WaitUntil((Func<bool>)(() => Initialized));
			callback();
		}

		public void PlayerConnect_C2SEvent(ulong clientId)
		{
			LethalPlugin.Log.LogInfo((object)$"Connexion reçue par : {clientId}");
			IDictionary<string, string> allConfigEntries = LethalPlugin.Instance.GetAllConfigEntries();
			string text = JsonConvert.SerializeObject((object)allConfigEntries);
			LethalPlugin.Log.LogInfo((object)("Sauvegarde des configs -> " + text));
			sendConfigServerMessage.SendAllClients(text, true);
		}

		public void LoadSharedData()
		{
			SaveSharedData saveSharedData = SaveManager.LoadSharedFile();
			if (saveSharedData == null)
			{
				LethalPlugin.Log.LogInfo((object)"données partagé innexistante");
				return;
			}
			LethalPlugin.Log.LogInfo((object)"Chargement du lobby, partage des données en cour");
			teamXP.Value = saveSharedData.xp;
			teamLevel.Value = saveSharedData.level;
			teamTotalValue.Value = saveSharedData.quota;
			teamXPRequired.Value = CalculateXPRequirement();
			LethalPlugin.Log.LogInfo((object)$"{saveSharedData.level} niveau actuel, {saveSharedData.xp} EXP, {saveSharedData.quota} Profit, {teamXPRequired.Value} teamXPRequired");
		}

		public IEnumerator LoadProfileData(string data)
		{
			LethalPlugin.Log.LogInfo((object)("Reception des données du joueur depuis le joueur host -> " + data));
			yield return (object)new WaitUntil((Func<bool>)(() => Initialized));
			if (loadedSave)
			{
				LethalPlugin.Log.LogWarning((object)"Données des joueurs charger par le Host.");
				yield return null;
			}
			loadedSave = true;
			SaveData saveData = JsonConvert.DeserializeObject<SaveData>(data);
			skillPoints = saveData.skillPoints;
			LethalPlugin.Log.LogDebug((object)$"skillPoints -> {skillPoints}");
			int skillCheck = 0;
			foreach (KeyValuePair<UpgradeType, int> skill in saveData.skillAllocation)
			{
				LethalPlugin.Log.LogDebug((object)$"{skill.Key} -> {skill.Value}");
				skillList.skills[skill.Key].SetLevel(skill.Value, triggerHostProfileSave: false);
				skillCheck += skill.Value;
				LethalPlugin.Log.LogDebug((object)$"Skill list -> {skillCheck}");
			}
			if (skillCheck + skillPoints < teamLevel.Value + 5)
			{
				LethalPlugin.Log.LogInfo((object)$"Skill check pour le niveau actuel, Ajout {teamLevel.Value + 5 - (skillCheck + skillPoints)} points.");
				skillPoints += teamLevel.Value + 5 - (skillCheck + skillPoints);
			}
			LP_NetworkManager.xpInstance.guiObj.UpdateAllStats();
		}

		public int CalculateXPRequirement()
		{
			int connectedPlayersAmount = StartOfRound.Instance.connectedPlayersAmount;
			int timesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota;
			int num = int.Parse(SkillConfig.hostConfig["Minimum EXP"]);
			int num2 = int.Parse(SkillConfig.hostConfig["Maximum EXP"]);
			int num3 = int.Parse(SkillConfig.hostConfig["EXP per player / EXP par Joueur"]);
			int num4 = connectedPlayersAmount * num3;
			int num5 = num + num4;
			int num6 = int.Parse(SkillConfig.hostConfig["Quota Multiplier"]);
			int num7 = timesFulfilledQuota * num6;
			num5 += (int)((float)num5 * ((float)num7 / 100f));
			if (num5 > num2)
			{
				num5 = num2;
			}
			LethalPlugin.Log.LogInfo((object)$"{connectedPlayersAmount} joueurs, {timesFulfilledQuota} quotas, {num} cout initial, {num4} valeur par personne additionnel, {num7} valeur du quota additionnel, {num5} cout total.");
			return num5;
		}

		public int GetXP()
		{
			return teamXP.Value;
		}

		public int GetLevel()
		{
			return teamLevel.Value;
		}

		public int GetProfit()
		{
			return teamTotalValue.Value;
		}

		public int GetSkillPoints()
		{
			return skillPoints;
		}

		public void SetSkillPoints(int num)
		{
			skillPoints = num;
		}

		public void EvaluateXPRequirements_C2SEvent(ulong clientId)
		{
			((MonoBehaviour)this).StartCoroutine(XPRequirementCoroutine());
		}

		public IEnumerator XPRequirementCoroutine()
		{
			yield return (object)new WaitForSeconds(0.5f);
			teamXPRequired.Value = CalculateXPRequirement();
		}

		public void UpdateTeamXP_C2SMessage(int xpToAdd, ulong clientId)
		{
			LethalNetworkVariable<int> obj = teamXP;
			obj.Value += xpToAdd;
			LethalNetworkVariable<int> obj2 = teamTotalValue;
			obj2.Value += xpToAdd;
			int num = GetXP();
			if (num >= teamXPRequired.Value)
			{
				int num2 = 0;
				while (num >= teamXPRequired.Value)
				{
					num2++;
					num -= teamXPRequired.Value;
				}
				teamXP.Value = num;
				LethalNetworkVariable<int> obj3 = teamLevel;
				obj3.Value += num2;
				updatePlayerSkillpointsServerMessage.SendAllClients(num2, true);
			}
		}

		public void UpdateSkillPoints_S2CMessage(int pointsToAdd)
		{
			skillPoints += pointsToAdd;
		}

		public void UpdateTeamLootLevel_C2SMessage(int change, ulong clientId)
		{
			int value = teamLootLevel.Value;
			if (value + change < 0)
			{
				teamLootLevel.Value = 0;
			}
			else
			{
				LethalNetworkVariable<int> obj = teamLootLevel;
				obj.Value += change;
			}
			LethalPlugin.Log.LogInfo((object)$"la valeur du taux de loot à changer -> {change} pour un total de {teamLootLevel.Value}.");
		}

		public void UpdateSPHandSlots_C2SMessage(int slotChange, ulong clientId)
		{
			if (!LethalPlugin.ReservedSlots)
			{
				LethalPlugin.Log.LogInfo((object)$"Client > Host(ServerRPC) : Mise à jour du Joueur {clientId} -> {slotChange} slots !");
				PlayerHandSlotData playerHandSlotData = new PlayerHandSlotData(clientId, slotChange);
				LethalPlugin.Log.LogDebug((object)$"Envoie des données à tous les joueurs par le joueur {playerHandSlotData.clientId} -> {playerHandSlotData.additionalSlots} slots !");
				updatePlayerHandSlotsServerMessage.SendAllClients(playerHandSlotData, true);
			}
		}

		public void UpdatePlayerHandSlots_S2CMessage(PlayerHandSlotData data)
		{
			LethalPlugin.Log.LogInfo((object)$"Host(ServerRPC) > Client : Mise à jour reçu par le joueur {data.clientId} -> {data.additionalSlots} slots !");
			if (data.additionalSlots == 0)
			{
				LethalPlugin.Log.LogWarning((object)"Valeur = 0, possible perte d'information, si les valeurs sont différente entre le Client > Host(ServerRPC) et le Host(ServerRPC) > Client. Sinon ignorez ce message.");
			}
			SetHandSlot(data.clientId, data.additionalSlots);
		}

		public void SetHandSlot(ulong playerID, int additionalSlots)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.playerClientId != playerID)
				{
					continue;
				}
				int num = 4 + additionalSlots;
				List<GrabbableObject> list = val.ItemSlots.ToList();
				if (val.currentItemSlot > num - 1)
				{
					HandSlots.SwitchItemSlots(val, num - 1);
				}
				for (int j = 0; j < list.Count; j++)
				{
					if (j > num - 1 && (Object)(object)list[j] != (Object)null)
					{
						HandSlots.SwitchItemSlots(val, j);
						val.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true);
						LethalPlugin.Log.LogWarning((object)"Le joueur porter un objet et viens de le lâcher !");
					}
				}
				val.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[num];
				for (int k = 0; k < list.Count; k++)
				{
					if (!((Object)(object)list[k] == (Object)null))
					{
						val.ItemSlots[k] = list[k];
					}
				}
				LethalPlugin.Log.LogDebug((object)$"Le joueur {playerID} dispose de {val.ItemSlots.Length} slots après le partage des configs");
				if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					LethalPlugin.Log.LogDebug((object)"Mise à jour de l'interface du joueur.");
					int num2 = (int)skillList.skills[UpgradeType.HandSlot].GetTrueValue();
					int num3 = (int)Math.Floor((double)(num2 / 100));
					int targetSlotCount = 4 + num3;
					HandSlots.UpdateHudSlots(targetSlotCount);
				}
				break;
			}
		}

		public void RefreshAllPlayerHandSlots_C2SEvent(ulong clientId)
		{
			if (LethalPlugin.ReservedSlots || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot))
			{
				return;
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (((Component)val).gameObject.activeSelf)
				{
					ulong playerClientId = val.playerClientId;
					int additionalSlots = val.ItemSlots.Length - 4;
					LethalPlugin.Log.LogInfo((object)"Valeurs rafraichis des slots pour l'ensemble des joueurs.");
					updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(playerClientId, additionalSlots), true);
				}
			}
		}

		public void SendHostConfig_S2CMessage(string serializedConfig)
		{
			IDictionary<string, string> dictionary = JsonConvert.DeserializeObject<IDictionary<string, string>>(serializedConfig);
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				SkillConfig.hostConfig[item.Key] = item.Value;
				LethalPlugin.Log.LogInfo((object)("Chargement des configs : " + item.Key + " = " + item.Value));
			}
			if (!Initialized)
			{
				Initialized = true;
				LP_NetworkManager.xpInstance = this;
				JumpHeight.savelevel = 0;
				LethalPlugin.Log.LogInfo((object)"Reset savelevel for Double jump");
				skillList = new SkillList();
				skillList.InitializeSkills();
				if (GameNetworkManager.Instance.isHostingGame)
				{
					LoadSharedData();
				}
				guiObj = new SkillsGUI();
				teamLootLevel.OnValueChanged += guiObj.TeamLootHudUpdate;
				skillPoints = teamLevel.Value + int.Parse(SkillConfig.hostConfig["Initial Statistics Point(s) / Point(s) de Statistiques Initial"]);
				calculateAllPlayersHandSlotsClientEvent.InvokeServer();
				evaluateXPRequirementClientEvent.InvokeServer();
			}
		}

		public void RequestSavedData_C2SMessage(ulong steamID, ulong clientId)
		{
			string text = SaveManager.LoadPlayerFile(steamID);
			PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId);
			sendProfileDataServerMessage.SendClient(text, playerController.actualClientId);
		}

		public void LoadProfileData_S2CMessage(string saveData)
		{
			LethalPlugin.Log.LogInfo((object)("Reception des configs : Host(ServerRPC) > Client -> " + saveData));
			if (saveData != null)
			{
				((MonoBehaviour)this).StartCoroutine(LoadProfileData(saveData));
			}
		}

		public void SaveProfileData_C2SMessage(string data, ulong clientId)
		{
			SaveProfileData saveProfileData = JsonConvert.DeserializeObject<SaveProfileData>(data);
			LethalPlugin.Log.LogInfo((object)$"Reception de la requête des données sauvegardé pour {saveProfileData.steamId}, données -> {JsonConvert.SerializeObject((object)saveProfileData.saveData)}");
			SaveManager.Save(saveProfileData.steamId, saveProfileData.saveData);
			SaveManager.SaveShared(teamXP.Value, teamLevel.Value, teamTotalValue.Value);
		}

		public void UpdatePlayerJumpHeight_C2SMessage(PlayerJumpHeightData playerData, ulong clientId)
		{
			LethalPlugin.Log.LogInfo((object)$"requête reçue par {clientId} [{playerData.clientId}] modification de la hauteur du saut {playerData.jumpSkillValue}");
			updatePlayerJumpForceServerMessage.SendAllClients(playerData, true);
		}

		public void UpdatePlayerJumpHeight_S2CMessage(PlayerJumpHeightData playerData)
		{
			PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(playerData.clientId);
			Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.JumpHeight];
			float num = (float)playerData.jumpSkillValue * skill.GetMultiplier() / 100f * 13f;
			playerController.jumpForce = 13f + num;
			LethalPlugin.Log.LogInfo((object)$"Mise à jour client {playerData.clientId} hauteur de saut. ajout {num} - {playerController.jumpForce}");
		}

		public int GetWisdomLevel(int playerId)
		{
			if (skillList != null && skillList.skills.ContainsKey(UpgradeType.Wisdom))
			{
				return skillList.skills[UpgradeType.Wisdom].GetLevel();
			}
			return 0;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalProgression";

		public const string PLUGIN_NAME = "LethalProgression";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace LethalProgression.Utils
{
	public static class DetectionUtils
	{
		private static int enemyLayerMask = 524288;

		private static float lastDetectionTime = -1f;

		private static float detectionCooldown = 1f;

		private static Dictionary<EnemyAI, GameObject> activeLights = new Dictionary<EnemyAI, GameObject>();

		public static List<EnemyAI> ScanAndLogNearbyEnemies(Vector3 center)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Expected O, but got Unknown
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			List<EnemyAI> list = new List<EnemyAI>();
			if (Time.time < lastDetectionTime + detectionCooldown)
			{
				return activeLights.Keys.Where((EnemyAI e) => (Object)(object)e != (Object)null && (Object)(object)((Component)e).gameObject != (Object)null).ToList();
			}
			lastDetectionTime = Time.time;
			Collider[] array = Physics.OverlapSphere(center, (float)Perception.PerceptionRange, enemyLayerMask);
			HashSet<EnemyAI> currentDetectedSet = new HashSet<EnemyAI>();
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				EnemyAI componentInParent = ((Component)val).GetComponentInParent<EnemyAI>();
				if ((Object)(object)componentInParent != (Object)null && !componentInParent.isEnemyDead && componentInParent.enemyType.canDie && currentDetectedSet.Add(componentInParent))
				{
					list.Add(componentInParent);
				}
			}
			List<EnemyAI> list2 = activeLights.Keys.Where((EnemyAI enemy) => !currentDetectedSet.Contains(enemy) || (Object)(object)enemy == (Object)null || (Object)(object)((Component)enemy).gameObject == (Object)null || enemy.isEnemyDead).ToList();
			foreach (EnemyAI item in list2)
			{
				if (activeLights.TryGetValue(item, out var value))
				{
					if ((Object)(object)value != (Object)null)
					{
						Object.Destroy((Object)(object)value);
					}
					activeLights.Remove(item);
				}
				else
				{
					if (!((Object)(object)item == (Object)null))
					{
						continue;
					}
					List<EnemyAI> list3 = (from pair in activeLights
						where (Object)(object)pair.Key == (Object)null
						select pair.Key).ToList();
					foreach (EnemyAI item2 in list3)
					{
						activeLights.Remove(item2);
					}
				}
			}
			foreach (EnemyAI item3 in list)
			{
				if (activeLights.ContainsKey(item3))
				{
					continue;
				}
				Transform val2 = ((Component)item3).transform;
				SkinnedMeshRenderer componentInChildren = ((Component)item3).GetComponentInChildren<SkinnedMeshRenderer>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					val2 = componentInChildren.rootBone ?? ((Component)componentInChildren).transform;
				}
				else
				{
					MeshRenderer componentInChildren2 = ((Component)item3).GetComponentInChildren<MeshRenderer>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						val2 = ((Component)componentInChildren2).transform;
					}
				}
				GameObject val3 = new GameObject("LethalProgression_BlinkingLight");
				val3.transform.SetParent(val2, false);
				val3.transform.localPosition = Vector3.up * 0.5f;
				val3.AddComponent<EnemyBlinkingLight>();
				activeLights.Add(item3, val3);
			}
			if (list.Count > 0)
			{
				string arg = string.Join(", ", list.Select((EnemyAI e) => e.enemyType.enemyName));
				LethalPlugin.Log.LogInfo((object)$"Nearby enemies detected ({list.Count}) within {Perception.PerceptionRange}m: {arg}");
			}
			return list;
		}

		public static void ClearAllEnemyLights()
		{
			foreach (KeyValuePair<EnemyAI, GameObject> activeLight in activeLights)
			{
				if ((Object)(object)activeLight.Value != (Object)null)
				{
					Object.Destroy((Object)(object)activeLight.Value);
				}
			}
			activeLights.Clear();
			LethalPlugin.Log.LogInfo((object)"Cleared all enemy detection lights.");
		}
	}
	[Serializable]
	public class EnemyLightConfig
	{
		public string enemyType;

		public Color lightColor = Color.red;

		public float intensity = 100f;

		public float range = 5f;

		public float blinkFrequency = 0.3f;
	}
	public class EnemyBlinkingLight : MonoBehaviour
	{
		private Light attachedLight;

		private float timer = 0f;

		private float baseIntensity = 100f;

		public float defaultBlinkFrequency = 0.3f;

		public float defaultIntensity = 0f;

		public float defaultRange = 0f;

		public Color defaultLightColor = Color.red;

		private static Dictionary<string, EnemyLightConfig> _enemyLightConfigs = new Dictionary<string, EnemyLightConfig>();

		public static void LoadEnemyLightConfigsFromString(string configString)
		{
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			_enemyLightConfigs.Clear();
			if (string.IsNullOrWhiteSpace(configString))
			{
				Debug.LogWarning((object)"[LethalProgression] EnemyLight config string is empty!");
				return;
			}
			Debug.Log((object)"[LethalProgression] Reading EnemyLight configs...");
			string[] array = configString.Split(';');
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (string.IsNullOrWhiteSpace(text))
				{
					continue;
				}
				string[] array3 = text.Split(':');
				if (array3.Length < 2)
				{
					continue;
				}
				string text2 = array3[0].Trim().ToLower();
				EnemyLightConfig enemyLightConfig = new EnemyLightConfig();
				enemyLightConfig.enemyType = text2;
				try
				{
					if (array3.Length > 1 && !string.IsNullOrWhiteSpace(array3[1]))
					{
						string[] array4 = array3[1].Split(',');
						if (array4.Length >= 3)
						{
							float num = float.Parse(array4[0]) / 255f;
							float num2 = float.Parse(array4[1]) / 255f;
							float num3 = float.Parse(array4[2]) / 255f;
							float num4 = ((array4.Length > 3) ? float.Parse(array4[3]) : 1f);
							enemyLightConfig.lightColor = new Color(num, num2, num3, num4);
						}
					}
					if (array3.Length > 2 && !string.IsNullOrWhiteSpace(array3[2]))
					{
						enemyLightConfig.intensity = float.Parse(array3[2]);
					}
					if (array3.Length > 3 && !string.IsNullOrWhiteSpace(array3[3]))
					{
						enemyLightConfig.range = float.Parse(array3[3]);
					}
					if (array3.Length > 4 && !string.IsNullOrWhiteSpace(array3[4]))
					{
						enemyLightConfig.blinkFrequency = float.Parse(array3[4]);
					}
					_enemyLightConfigs[text2] = enemyLightConfig;
					Debug.Log((object)$"[LethalProgression] Registered light config for {text2} => Color:{enemyLightConfig.lightColor}, Intensity:{enemyLightConfig.intensity}, Range:{enemyLightConfig.range}, Frequency:{enemyLightConfig.blinkFrequency}");
				}
				catch (Exception ex)
				{
					Debug.LogWarning((object)("[LethalProgression] Error parsing light config for " + text2 + ": " + ex.Message));
				}
			}
		}

		private void Awake()
		{
			attachedLight = ((Component)this).gameObject.AddComponent<Light>();
			EnemyAI componentInParent = ((Component)this).GetComponentInParent<EnemyAI>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				ConfigureLightForEnemy(componentInParent);
			}
			else
			{
				ConfigureDefaultLight();
			}
			((Behaviour)attachedLight).enabled = true;
		}

		private void ConfigureLightForEnemy(EnemyAI enemy)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			string text = ((object)enemy.enemyType).ToString();
			string text2 = text.Replace("(Clone)", "").Replace("(EnemyType)", "").Trim()
				.ToLower();
			bool flag = false;
			foreach (KeyValuePair<string, EnemyLightConfig> enemyLightConfig in _enemyLightConfigs)
			{
				if (text2.Contains(enemyLightConfig.Key))
				{
					EnemyLightConfig value = enemyLightConfig.Value;
					attachedLight.color = value.lightColor;
					baseIntensity = value.intensity;
					attachedLight.intensity = baseIntensity;
					attachedLight.range = value.range;
					defaultBlinkFrequency = value.blinkFrequency;
					flag = true;
					Debug.Log((object)("[LethalProgression] Applied custom light settings for enemy '" + text2 + "'"));
					break;
				}
			}
			if (!flag)
			{
				ConfigureDefaultLight();
				Debug.Log((object)("[LethalProgression] No custom light settings found for enemy '" + text2 + "', using defaults"));
			}
		}

		private void ConfigureDefaultLight()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			attachedLight.color = defaultLightColor;
			baseIntensity = defaultIntensity;
			attachedLight.intensity = baseIntensity;
			attachedLight.range = defaultRange;
		}

		private void Update()
		{
			if ((Object)(object)attachedLight == (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			timer += Time.deltaTime;
			float intensity = baseIntensity * (0.2f + 0.8f * ((Mathf.Sin(timer * defaultBlinkFrequency * MathF.PI) + 1f) / 2f));
			attachedLight.intensity = intensity;
		}
	}
	[HarmonyPatch]
	public class EnemyPerceptionManager : MonoBehaviour
	{
		private static Dictionary<EnemyAI, float> detectedEnemies = new Dictionary<EnemyAI, float>();

		private static float GetDetectionRange()
		{
			if (!Object.op_Implicit((Object)(object)LP_NetworkManager.xpInstance) || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Perception))
			{
				return 0f;
			}
			float result = 50f;
			float result3;
			if (SkillConfig.hostConfig.ContainsKey("Perception Range / Portée de perception"))
			{
				if (float.TryParse(SkillConfig.hostConfig["Perception Range / Portée de perception"], out var result2))
				{
					result = result2;
				}
			}
			else if (SkillConfig.hostConfig.ContainsKey("Perception : range / Perception : portée") && float.TryParse(SkillConfig.hostConfig["Perception : range / Perception : portée"], out result3))
			{
				result = result3;
			}
			return result;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "Update")]
		private static void DetectEnemies(PlayerControllerB __instance)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)LP_NetworkManager.xpInstance) || !LP_NetworkManager.xpInstance.skillList.IsSkillListValid() || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Perception))
			{
				return;
			}
			if (__instance.isPlayerDead)
			{
				detectedEnemies.Clear();
				PerceptionBar.ClearDetectedEnemies();
				return;
			}
			if (LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Perception].GetLevel() < 1)
			{
				detectedEnemies.Clear();
				PerceptionBar.ClearDetectedEnemies();
				return;
			}
			float detectionRange = GetDetectionRange();
			EnemyAI[] array = Object.FindObjectsOfType<EnemyAI>();
			Dictionary<EnemyAI, float> dictionary = new Dictionary<EnemyAI, float>();
			List<string> list = new List<string>();
			EnemyAI[] array2 = array;
			foreach (EnemyAI val in array2)
			{
				if ((Object)(object)val == (Object)null || val.isEnemyDead)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position);
				if (num <= detectionRange)
				{
					dictionary[val] = num;
					string text = ExtractEnemyType(val);
					if (!string.IsNullOrEmpty(text) && !list.Contains(text))
					{
						list.Add(text);
					}
				}
			}
			detectedEnemies = dictionary;
			PerceptionBar.ClearDetectedEnemies();
			foreach (string item in list)
			{
				PerceptionBar.AddDetectedEnemy(item);
			}
			PerceptionBar.UpdatePerceptionUI();
		}

		private static string ExtractEnemyType(EnemyAI enemy)
		{
			string text = ((object)enemy.enemyType).ToString();
			return text.Replace("(Clone)", "").Replace("(EnemyType)", "").Trim()
				.ToLower();
		}
	}
}
namespace LethalProgression.GUI
{
	public class SkillButtonState : MonoBehaviour
	{
		public Color originalColor = Color.white;
	}
	[HarmonyPatch]
	internal class GUIUpdate
	{
		public static bool isMenuOpen;

		public static SkillsGUI guiInstance;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "Update")]
		private static void SkillMenuUpdate(QuickMenuManager __instance)
		{
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			if (guiInstance == null || !Object.op_Implicit((Object)(object)guiInstance.mainPanel))
			{
				return;
			}
			if (!isMenuOpen)
			{
				guiInstance.mainPanel.SetActive(false);
			}
			else
			{
				if (!isMenuOpen)
				{
					return;
				}
				if (bool.Parse(SkillConfig.hostConfig["Respe Only in the ship / Respé Uniquement dans le vaisseau"]) && !bool.Parse(SkillConfig.hostConfig["Respe disabled / Respé désactivé"]))
				{
					if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom)
					{
						guiInstance.SetUnspec(show: true);
					}
					else
					{
						guiInstance.SetUnspec(show: false);
					}
				}
				if (bool.Parse(SkillConfig.hostConfig["Respe Only in orbit / Respé Uniquement en orbit"]))
				{
					if (StartOfRound.Instance.inShipPhase)
					{
						guiInstance.SetUnspec(show: true);
					}
					else
					{
						guiInstance.SetUnspec(show: false);
					}
				}
				if (bool.Parse(SkillConfig.hostConfig["Respe disabled / Respé désactivé"]))
				{
					guiInstance.SetUnspec(show: false);
				}
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
				GameObject gameObject = ((Component)guiInstance.mainPanel.transform.GetChild(2)).gameObject;
				float x = gameObject.transform.position.x;
				Rect rect = gameObject.GetComponent<RectTransform>().rect;
				float num = x - ((Rect)(ref rect)).width;
				float x2 = gameObject.transform.position.x;
				rect = gameObject.GetComponent<RectTransform>().rect;
				float num2 = x2 + ((Rect)(ref rect)).width;
				float y = gameObject.transform.position.y;
				rect = gameObject.GetComponent<RectTransform>().rect;
				float num3 = y - ((Rect)(ref rect)).height;
				float y2 = gameObject.transform.position.y;
				rect = gameObject.GetComponent<RectTransform>().rect;
				float num4 = y2 + ((Rect)(ref rect)).height;
				if (val.x >= num && val.x <= num2)
				{
					if (val.y >= num3 && val.y <= num4)
					{
						((Component)guiInstance.mainPanel.transform.GetChild(2).GetChild(2)).gameObject.SetActive(true);
					}
					else
					{
						((Component)guiInstance.mainPanel.transform.GetChild(2).GetChild(2)).gameObject.SetActive(false);
					}
				}
				else
				{
					((Component)guiInstance.mainPanel.transform.GetChild(2).GetChild(2)).gameObject.SetActive(false);
				}
				guiInstance.mainPanel.SetActive(true);
				GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons");
				val2.SetActive(false);
				GameObject val3 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList");
				val3.SetActive(false);
				RealTimeUpdateInfo();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")]
		private static void SkillMenuClose(QuickMenuManager __instance)
		{
			isMenuOpen = false;
		}

		private static void RealTimeUpdateInfo()
		{
			GameObject gameObject = ((Component)guiInstance.mainPanel.transform.GetChild(2)).gameObject;
			gameObject = ((Component)gameObject.transform.GetChild(1)).gameObject;
			TextMeshProUGUI component = gameObject.GetComponent<TextMeshProUGUI>();
			((TMP_Text)component).text = LP_NetworkManager.xpInstance.GetSkillPoints().ToString();
		}
	}
	internal class SkillsGUI
	{
		public GameObject mainPanel;

		public GameObject infoPanel;

		public GameObject templateSlot;

		public Skill activeSkill;

		public int shownSkills = 0;

		public List<GameObject> skillButtonsList = new List<GameObject>();

		public List<GameObject> separatorsList = new List<GameObject>();

		public static HashSet<UpgradeType> simplifiedTextSkills = new HashSet<UpgradeType>
		{
			UpgradeType.Doublejump,
			UpgradeType.Nightvision,
			UpgradeType.Perception
		};

		public SkillsGUI()
		{
			CreateSkillMenu();
			GUIUpdate.guiInstance = this;
		}

		public void OpenSkillMenu()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			GUIUpdate.isMenuOpen = true;
			mainPanel.SetActive(true);
			if (Object.op_Implicit((Object)(object)GameObject.Find("SkillMenu/Scroll/SkillContents")))
			{
				GameObject.Find("SkillMenu/Scroll/SkillContents").gameObject.transform.localScale = new Vector3(0.327f, 0.3f, 1f);
			}
		}

		public void CreateSkillMenu()
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			mainPanel = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("SkillMenu"));
			((Object)mainPanel).name = "SkillMenu";
			mainPanel.SetActive(false);
			templateSlot = Object.Instantiate<GameObject>(GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory/Slot3"));
			((Object)templateSlot).name = "TemplateSlot";
			templateSlot.SetActive(false);
			infoPanel = ((Component)mainPanel.transform.GetChild(1)).gameObject;
			infoPanel.SetActive(false);
			GameObject gameObject = ((Component)mainPanel.transform.GetChild(4)).gameObject;
			gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(BackButton));
			shownSkills = 0;
			if (LP_NetworkManager.xpInstance.skillList.skills == null)
			{
				return;
			}
			Dictionary<string, List<UpgradeType>> dictionary = new Dictionary<string, List<UpgradeType>>();
			dictionary["Stats"] = new List<UpgradeType>
			{
				UpgradeType.Resist,
				UpgradeType.HPRegen,
				UpgradeType.Stamina,
				UpgradeType.SprintSpeed,
				UpgradeType.JumpHeight,
				UpgradeType.Strength,
				UpgradeType.Critical,
				UpgradeType.Oxygen,
				UpgradeType.Battery,
				UpgradeType.Vision,
				UpgradeType.Value,
				UpgradeType.Wisdom,
				UpgradeType.HandSlot
			};
			dictionary["Capacity"] = new List<UpgradeType>
			{
				UpgradeType.Doublejump,
				UpgradeType.Nightvision,
				UpgradeType.Perception
			};
			HashSet<UpgradeType> hashSet = new HashSet<UpgradeType>();
			bool flag = true;
			foreach (KeyValuePair<string, List<UpgradeType>> item in dictionary)
			{
				if (!flag)
				{
					AddSkillSeparator(item.Key + "_separator");
				}
				else
				{
					flag = false;
				}
				foreach (UpgradeType item2 in item.Value)
				{
					if (LP_NetworkManager.xpInstance.skillList.skills.ContainsKey(item2))
					{
						Skill skill = LP_NetworkManager.xpInstance.skillList.skills[item2];
						LethalPlugin.Log.LogInfo((object)("Creating button for " + skill.GetShortName()));
						GameObject val = SetupUpgradeButton(skill);
						LethalPlugin.Log.LogInfo((object)"Setup passed!");
						skillButtonsList.Add(val);
						LethalPlugin.Log.LogInfo((object)"Added to skill list..");
						LoadSkillData(skill, val);
						hashSet.Add(item2);
					}
				}
			}
			List<Skill> list = new List<Skill>();
			foreach (KeyValuePair<UpgradeType, Skill> skill2 in LP_NetworkManager.xpInstance.skillList.skills)
			{
				if (!hashSet.Contains(skill2.Key))
				{
					list.Add(skill2.Value);
				}
			}
			if (list.Count > 0)
			{
				AddSkillSeparator("Other_separator");
				foreach (Skill item3 in list)
				{
					LethalPlugin.Log.LogInfo((object)("Creating button for remaining skill: " + item3.GetShortName()));
					GameObject val2 = SetupUpgradeButton(item3);
					skillButtonsList.Add(val2);
					LoadSkillData(item3, val2);
				}
			}
			TeamLootHudUpdate(0);
		}

		public void BackButton()
		{
			GUIUpdate.isMenuOpen = false;
			GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons");
			val.SetActive(true);
			GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList");
			val2.SetActive(true);
		}

		public void SetUnspec(bool show)
		{
			GameObject gameObject = ((Component)infoPanel.transform.GetChild(6)).gameObject;
			GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(7)).gameObject;
			GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(8)).gameObject;
			gameObject.SetActive(show);
			gameObject2.SetActive(show);
			gameObject3.SetActive(show);
			if (!bool.Parse(SkillConfig.hostConfig["Respe disabled / Respé désactivé"]))
			{
				GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(9)).gameObject;
				gameObject4.SetActive(!show);
			}
			if (bool.Parse(SkillConfig.hostConfig["Respe Only in orbit / Respé Uniquement en orbit"]))
			{
				GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(9)).gameObject;
				((TMP_Text)((Component)gameObject5.transform).GetComponent<TextMeshProUGUI>()).SetText("Respé Disponible en Orbit", true);
			}
		}

		public GameObject AddSkillSeparator(string separatorName = "SEPARATOR")
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			LethalPlugin.Log.LogInfo((object)("Adding separator: " + separatorName));
			GameObject val = new GameObject(separatorName);
			RectTransform val2 = val.AddComponent<RectTransform>();
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = new Color(0.8f, 0f, 0f, 1f);
			GameObject gameObject = ((Component)mainPanel.transform.Find("Scroll")).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				LethalPlugin.Log.LogError((object)"Cannot find Scroll object");
				Object.Destroy((Object)(object)val);
				return null;
			}
			GameObject gameObject2 = ((Component)gameObject.transform.Find("SkillContents")).gameObject;
			if ((Object)(object)gameObject2 == (Object)null)
			{
				LethalPlugin.Log.LogError((object)"Cannot find SkillContents object");
				Object.Destroy((Object)(object)val);
				return null;
			}
			val.transform.SetParent(gameObject2.transform, false);
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(1f, 0f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.sizeDelta = new Vector2(0f, 25f);
			LayoutElement val4 = val.AddComponent<LayoutElement>();
			val4.minHeight = 25f;
			val4.preferredHeight = 25f;
			val4.flexibleHeight = 0f;
			val4.minWidth = -1f;
			val4.preferredWidth = -1f;
			val.SetActive(true);
			LethalPlugin.Log.LogInfo((object)"Separator created and added to hierarchy");
			shownSkills++;
			return val;
		}

		public GameObject SetupUpgradeButton(Skill skill)
		{
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Expected O, but got Unknown
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Expected O, but got Unknown
			GameObject gameObject = ((Component)mainPanel.transform.GetChild(0)).gameObject;
			GameObject val = Object.Instantiate<GameObject>(gameObject);
			if (!Object.op_Implicit((Object)(object)gameObject))
			{
				LethalPlugin.Log.LogError((object)"Couldn't find template button!");
				return null;
			}
			((Object)val).name = skill.GetShortName();
			GameObject gameObject2 = ((Component)mainPanel.transform.GetChild(3)).gameObject;
			GameObject gameObject3 = ((Component)gameObject2.transform.GetChild(1)).gameObject;
			val.transform.SetParent(gameObject3.transform, false);
			shownSkills++;
			GameObject gameObject4 = ((Component)val.transform.GetChild(0)).gameObject;
			((TMP_Text)gameObject4.GetComponent<TextMeshProUGUI>()).SetText(skill.GetShortName(), true);
			GameObject gameObject5 = ((Component)val.transform.GetChild(1)).gameObject;
			((TMP_Text)gameObject5.GetComponent<TextMeshProUGUI>()).SetText("", true);
			GameObject gameObject6 = ((Component)val.transform.GetChild(2)).gameObject;
			((TMP_Text)gameObject6.GetComponent<TextMeshProUGUI>()).SetText("[" + skill.GetLevel() + " " + skill.GetAttribute() + "]", true);
			((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() ?? "", true);
			val.SetActive(true);
			val.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				UpdateStatInfo(skill);
			});
			return val;
		}

		public void LoadSkillData(Skill skill, GameObject skillButton)
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			if (skill._teamShared)
			{
				return;
			}
			GameObject gameObject = ((Component)skillButton.transform.GetChild(1)).gameObject;
			((TMP_Text)gameObject.GetComponent<TextMeshProUGUI>()).SetText("", true);
			GameObject gameObject2 = ((Component)skillButton.transform.GetChild(2)).gameObject;
			Image component = skillButton.GetComponent<Image>();
			Outline component2 = skillButton.GetComponent<Outline>();
			if (simplifiedTextSkills.Contains(skill.GetUpgradeType()))
			{
				bool flag = skill.GetMaxLevel() != 99999 && skill.GetLevel() >= skill.GetMaxLevel();
				if (flag)
				{
					if ((Object)(object)component2 != (Object)null)
					{
						((Shadow)component2).effectColor = new Color(0f, 1f, 0f, 1f);
						((Shadow)component2).effectDistance = new Vector2(2f, 2f);
					}
					if ((Object)(object)component != (Object)null)
					{
						SkillButtonState skillButtonState = default(SkillButtonState);
						if (!skillButton.TryGetComponent<SkillButtonState>(ref skillButtonState))
						{
							skillButtonState = skillButton.AddComponent<SkillButtonState>();
							skillButtonState.originalColor = ((Graphic)component).color;
						}
						((Graphic)component).color = new Color(0f, 0.7f, 0f, 1f);
					}
				}
				else
				{
					if ((Object)(object)component2 != (Object)null)
					{
						((Shadow)component2).effectColor = Color.white;
						((Shadow)component2).effectDistance = new Vector2(1f, 1f);
					}
					if ((Object)(object)component != (Object)null)
					{
						SkillButtonState skillButtonState2 = default(SkillButtonState);
						if (skillButton.TryGetComponent<SkillButtonState>(ref skillButtonState2))
						{
							((Graphic)component).color = skillButtonState2.originalColor;
						}
						else
						{
							((Graphic)component).color = new Color(1f, 1f, 1f, 1f);
						}
					}
				}
				if (bool.Parse(SkillConfig.hostConfig["Language used : Frensh / Langue utilisé : Français"]))
				{
					if (skill.GetMaxLevel() == 99999)
					{
						if (skill.GetLevel() == 0)
						{
							((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "</color>] " + skill.GetAttribute() + ".", true);
						}
						else
						{
							((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "</color>] " + skill.GetAttribute() + ".", true);
						}
					}
					else if (skill.GetLevel() == 0)
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] " + skill.GetAttribute() + ".", true);
					}
					else if (flag)
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#00ff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] " + skill.GetAttribute() + ".", true);
					}
					else
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] " + skill.GetAttribute() + ".", true);
					}
				}
				else if (skill.GetMaxLevel() == 99999)
				{
					if (skill.GetLevel() == 0)
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "</color>] " + skill.GetAttribute() + ".", true);
					}
					else
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "</color>] " + skill.GetAttribute() + ".", true);
					}
				}
				else if (skill.GetLevel() == 0)
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] " + skill.GetAttribute() + ".", true);
				}
				else if (flag)
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#00ff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] " + skill.GetAttribute() + ".", true);
				}
				else
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] " + skill.GetAttribute() + ".", true);
				}
			}
			else if (bool.Parse(SkillConfig.hostConfig["Language used : Frensh / Langue utilisé : Français"]))
			{
				if (skill.GetMaxLevel() == 99999)
				{
					if (skill.GetLevel() == 0)
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "</color>] Augmente de <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> " + skill.GetAttribute() + ".", true);
					}
					else
					{
						((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "</color>] Augmente de <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> " + skill.GetAttribute() + ".", true);
					}
				}
				else if (skill.GetLevel() == 0)
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Augmente de <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "%) " + skill.GetAttribute() + ".", true);
				}
				else if (skill.GetLevel() >= skill.GetMaxLevel())
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#00ff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Augmente de <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "%) " + skill.GetAttribute() + ".", true);
				}
				else
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Augmente de <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "%) " + skill.GetAttribute() + ".", true);
				}
			}
			else if (skill.GetMaxLevel() == 99999)
			{
				if (skill.GetLevel() == 0)
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "</color>] Increase by <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> " + skill.GetAttribute() + ".", true);
				}
				else
				{
					((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "</color>] Increase by <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> " + skill.GetAttribute() + ".", true);
				}
			}
			else if (skill.GetLevel() == 0)
			{
				((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Increase by <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "%) " + skill.GetAttribute() + ".", true);
			}
			else if (skill.GetLevel() >= skill.GetMaxLevel())
			{
				((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#00ff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Increase by <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "%) " + skill.GetAttribute() + ".", true);
			}
			else
			{
				((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Increase by <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "%) " + skill.GetAttribute() + ".", true);
			}
			((TMP_Text)skillButton.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() ?? "", true);
		}

		public void UpdateAllStats()
		{
			foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills)
			{
				if (!skill.Value._teamShared)
				{
					GameObject skillButton = skillButtonsList.Find((GameObject x) => ((Object)x).name == skill.Value.GetShortName());
					LoadSkillData(skill.Value, skillButton);
				}
			}
		}

		public void UpdateStatInfo(Skill skill)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Expected O, but got Unknown
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Expected O, but got Unknown
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Expected O, but got Unknown
			if (!infoPanel.activeSelf)
			{
				infoPanel.SetActive(true);
			}
			TextMeshProUGUI component = ((Component)infoPanel.transform.GetChild(0)).gameObject.GetComponent<TextMeshProUGUI>();
			TextMeshProUGUI component2 = ((Component)infoPanel.transform.GetChild(1)).gameObject.GetComponent<TextMeshProUGUI>();
			TextMeshProUGUI component3 = ((Component)infoPanel.transform.GetChild(2)).gameObject.GetComponent<TextMeshProUGUI>();
			activeSkill = skill;
			((TMP_Text)component).SetText(skill.GetName(), true);
			((TMP_Text)component2).SetText("", true);
			((TMP_Text)component3).SetText(skill.GetDescription(), true);
			GameObject gameObject = ((Component)infoPanel.transform.GetChild(3)).gameObject;
			GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(4)).gameObject;
			GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(5)).gameObject;
			gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				AddSkillPoint(skill, 5);
			});
			gameObject2.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				AddSkillPoint(skill, 2);
			});
			gameObject3.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject3.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				AddSkillPoint(skill, 1);
			});
			GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(6)).gameObject;
			GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(7)).gameObject;
			GameObject gameObject6 = ((Component)infoPanel.transform.GetChild(8)).gameObject;
			gameObject4.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject4.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				RemoveSkillPoint(skill, 5);
			});
			gameObject5.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject5.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				RemoveSkillPoint(skill, 2);
			});
			gameObject6.GetComponent<Button>().onClick = new ButtonClickedEvent();
			((UnityEvent)gameObject6.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				RemoveSkillPoint(skill, 1);
			});
		}

		public void AddSkillPoint(Skill skill, int amt)
		{
			if (LP_NetworkManager.xpInstance.GetSkillPoints() <= 0)
			{
				return;
			}
			int skillPoints = LP_NetworkManager.xpInstance.GetSkillPoints();
			if (skillPoints < amt)
			{
				amt = skillPoints;
			}
			if (skill.GetLevel() + amt > skill.GetMaxLevel())
			{
				amt = skill.GetMaxLevel() - skill.GetLevel();
			}
			LP_NetworkManager.xpInstance.SetSkillPoints(LP_NetworkManager.xpInstance.GetSkillPoints() - amt);
			skill.AddLevel(amt);
			UpdateStatInfo(skill);
			foreach (GameObject skillButtons in skillButtonsList)
			{
				if (((Object)skillButtons).name == skill.GetShortName())
				{
					LoadSkillData(skill, skillButtons);
				}
			}
		}

		public void RemoveSkillPoint(Skill skill, int amt)
		{
			if (skill.GetLevel() == 0)
			{
				return;
			}
			int level = skill.GetLevel();
			if (level < amt)
			{
				amt = level;
			}
			LP_NetworkManager.xpInstance.SetSkillPoints(LP_NetworkManager.xpInstance.GetSkillPoints() + amt);
			skill.AddLevel(-amt);
			UpdateStatInfo(skill);
			foreach (GameObject skillButtons in skillButtonsList)
			{
				if (((Object)skillButtons).name == skill.GetShortName())
				{
					LoadSkillData(skill, skillButtons);
				}
			}
		}

		public void TeamLootHudUpdate(int newValue)
		{
			foreach (GameObject skillButtons in skillButtonsList)
			{
				if (!(((Object)skillButtons).name == "         <color=#FF75FB>CHANCE</color>"))
				{
					continue;
				}
				Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value];
				LoadSkillData(skill, skillButtons);
				GameObject gameObject = ((Component)skillButtons.transform.GetChild(0)).gameObject;
				((TMP_Text)gameObject.GetComponent<TextMeshProUGUI>()).SetText(skill.GetShortName(), true);
				GameObject gameObject2 = ((Component)skillButtons.transform.GetChild(1)).gameObject;
				((TMP_Text)skillButtons.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() ?? "", true);
				float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier();
				float num = (float)newValue * multiplier;
				GameObject gameObject3 = ((Component)skillButtons.transform.GetChild(2)).gameObject;
				if (bool.Parse(SkillConfig.hostConfig["Language used : Frensh / Langue utilisé : Français"]))
				{
					if (skill.GetMaxLevel() == 99999)
					{
						if (skill.GetLevel() == 0)
						{
							((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "</color>] Augmente de <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Bonus d'équipe total : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
						}
						else
						{
							((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "</color>] Augmente de <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Bonus d'équipe total : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
						}
					}
					else if (skill.GetLevel() == 0)
					{
						((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Augmente de <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "% (Bonus d'équipe total : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
					}
					else if (skill.GetLevel() >= skill.GetMaxLevel())
					{
						((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#00ff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Augmente de <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "% (Bonus d'équipe total : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
					}
					else
					{
						((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Augmente de <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "% (Bonus d'équipe total : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
					}
				}
				else if (skill.GetMaxLevel() == 99999)
				{
					if (skill.GetLevel() == 0)
					{
						((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "</color>] Increases by <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Total Team Bonus : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
					}
					else
					{
						((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "</color>] Increases by <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Total Team Bonus : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
					}
				}
				else if (skill.GetLevel() == 0)
				{
					((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ff0000>" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Increases by <color=#ff0000>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "% (Total Team Bonus : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
				}
				else if (skill.GetLevel() >= skill.GetMaxLevel())
				{
					((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#00ff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Increases by <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "% (Total Team Bonus : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
				}
				else
				{
					((TMP_Text)gameObject3.GetComponent<TextMeshProUGUI>()).SetText("[<color=#ffff00>+" + skill.GetLevel() + "/" + skill.GetMaxLevel() + "</color>] Increases by <color=#00ffff>" + (float)skill.GetLevel() * skill.GetMultiplier() + "%</color> (Max " + (float)skill.GetMaxLevel() * skill.GetMultiplier() + "% (Total Team Bonus : <color=#ff00ff>" + num + "%</color>) " + skill.GetAttribute() + ".", true);
				}
				LethalPlugin.Log.LogInfo((object)$"Setting team value hud to {num}");
			}
		}
	}
}
namespace LethalProgression.Skills
{
	public enum UpgradeType
	{
		HPRegen,
		Stamina,
		Battery,
		HandSlot,
		Value,
		Oxygen,
		JumpHeight,
		SprintSpeed,
		Strength,
		Resist,
		Critical,
		Vision,
		Wisdom,
		Doublejump,
		Nightvision,
		Perception
	}
	internal class SkillList
	{
		public static int OxyNoSpam = 0;

		public static string RespecText = "...";

		public static string ConsT = "<color=#8A7B3F>CONSTITUTION</color>";

		public static string ConsD = "         <color=#8A7B3F>CONSTITUTION</color>";

		public static string Cons = ": resistance to monster damage, (Max 90%).";

		public static string VitaT = "<color=#00cc00>VITALITY</color>";

		public static string VitaD = "         <color=#00cc00>VITALITY</color>";

		public static string Vita = ": passive health regeneration";

		public static string EnduT = "<color=#FFAB00>STAMINA</color>";

		public static string EnduD = "         <color=#FFAB00>STAMINA</color>";

		public static string Endu = ": the maximum amount of endurance";

		public static string ViteT = "<color=#6DF0F9>SPEED</color>";

		public static string ViteD = "         <color=#6DF0F9>SPEED</color>";

		public static string Vite = ": sprint speed";

		public static string ForcT = "<color=#C4774A>STRENGTH</color>";

		public static string ForcD = "         <color=#C4774A>STRENGTH</color>";

		public static string Forc = ": the ability to carry heavy loads";

		public static string AgiT = "<color=#00FF80>AGILITY</color>";

		public static string AgiD = "         <color=#00FF80>AGILITY</color>";

		public static string Agi = ": the height of the jumps";

		public static string CritT = "<color=#ff4444>CRITICAL</color>";

		public static string CritD = "         <color=#ff4444>CRITICAL</color>";

		public static string Crit = ": The chance of landing a critical hit with melee weapons";

		public static string EnerT = "<color=#F2FC66>ENERGY</color>";

		public static string EnerD = "         <color=#F2FC66>ENERGY</color>";

		public static string Ener = ": battery life";

		public static string VisiT = "<color=#ccccff>VISION</color>";

		public static string VisiD = "         <color=#ccccff>VISION</color>";

		public static string Visi = ": The duration and recharge speed of <color=#ACACE9>Vision nocturne</color> <color=#ff00ff>(Capacity requiered)</color>.";

		public static string OxygT = "<color=#3399FF>OXYGEN</color>";

		public static string OxygD = "         <color=#3399FF>OXYGEN</color>";

		public static string Oxyg = ": the duration of breathing underwater";

		public static string SpecT = "<color=#5341AB>SPECIAL</color>";

		public static string SpecD = "         <color=#5341AB>SPECIAL</color>";

		public static string Spec = ": the quantity of transportable object";

		public static string ChanT = "<color=#FF75FB>CHANCE</color>";

		public static string ChanD = "         <color=#FF75FB>CHANCE</color>";

		public static string Chan = ": the value of the items to be collected";

		public static string WisT = "<color=#ff007f>WISDOM</color>";

		public static string WisD = "         <color=#ff007f>WISDOM</color>";

		public static string Wis = ": the additionnal exp gain to kill monsters";

		public static string PerT = "<color=#330066>PERCEPTION</color>";

		public static string PerD = "         <color=#330066>PERCEPTION</color>";

		public static string Per = "To unlock the <color=#330066>Perception</color> ability. Allows you to detect monsters more easily within a radius of " + int.Parse(SkillConfig.hostConfig["Perception : range / Perception : portée"]) + "m.";

		public static string DoubT = "<color=#00cc66>DOUBLEJUMP</color>";

		public static string DoubD = "         <color=#00cc66>DOUBLEJUMP</color>";

		public static string Doub = "To unlock the <color=#00cc66>Double Jump</color> ability. Allows you to double jump (key configurable in the game options).";

		public static string NighT = "<color=#ACACE9>NIGHTVISION</color>";

		public static string NighD = "         <color=#ACACE9>NIGHTVISION</color>";

		public static string Nigh = "To unlock the <color=#ACACE9>Nightvision</color> ability. Allows you to temporarily activate night vision (key configurable in the game options).";

		public Dictionary<UpgradeType, Skill> skills = new Dictionary<UpgradeType, Skill>();

		public void CreateSkill(UpgradeType upgrade, string name, string description, string shortname, string attribute, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false)
		{
			Skill value = new Skill(name, description, shortname, attribute, upgrade, cost, maxLevel, multiplier, callback, teamShared);
			skills.Add(upgrade, value);
		}

		public bool IsSkillListValid()
		{
			if (skills.Count == 0)
			{
				return false;
			}
			return true;
		}

		public bool IsSkillValid(UpgradeType upgrade)
		{
			if (!skills.ContainsKey(upgrade))
			{
				if (!skills.ContainsKey(UpgradeType.Oxygen))
				{
					if (OxyNoSpam == 0)
					{
						LethalPlugin.Log.LogInfo((object)("Skill " + upgrade.ToString() + " is not in the skill list!"));
						OxyNoSpam = 1;
						return false;
					}
					return false;
				}
				LethalPlugin.Log.LogInfo((object)("Skill " + upgrade.ToString() + " is not in the skill list!"));
				return false;
			}
			return true;
		}

		public Skill GetSkill(UpgradeType upgrade)
		{
			if (!IsSkillValid(upgrade))
			{
				return null;
			}
			return skills[upgrade];
		}

		public Dictionary<UpgradeType, Skill> GetSkills()
		{
			return skills;
		}

		public void InitializeSkills()
		{
			if (bool.Parse(SkillConfig.hostConfig["Language used : Frensh / Langue utilisé : Français"]))
			{
				if (bool.Parse(SkillConfig.hostConfig["Respe Only in the ship / Respé Uniquement dans le vaisseau"]) && !bool.Parse(SkillConfig.hostConfig["Respe disabled / Respé désactivé"]))
				{
					RespecText = "Vous pouvez ajouter des points de caractéristiques à tout moment. Pour modifier votre spécialisation vous devez être à bord du vaisseau.";
				}
				else if (bool.Parse(SkillConfig.hostConfig["Respe Only in orbit / Respé Uniquement en orbit"]))
				{
					RespecText = "Vous pouvez ajouter des points de caractéristiques à tout moment. Pour modifier votre spécialisation vous devez être en Orbit.";
				}
				else if (bool.Parse(SkillConfig.hostConfig["Respe disabled / Respé désactivé"]))
				{
					RespecText = "Vous pouvez ajouter des points de caractéristiques à tout moment. Toutefois, <color=#ff0000>Attention</color> ces choix sont définitifs et irréversibles.";
				}
				else
				{
					RespecText = "Vous pouvez modifier vos points de caractéristiques à tout moment.";
				}
				ConsT = "<color=#8A7B3F>CONSTITUTION</color>";
				ConsD = "         <color=#8A7B3F>CONSTITUTION</color>";
				Cons = "la résistance aux dégats des monstres, (Max 90%).";
				VitaT = "<color=#00cc00>VITALITE</color>";
				VitaD = "         <color=#00cc00>VITALITE</color>";
				Vita = "la régénération de points de vie passif";
				EnduT = "<color=#FFAB00>ENDURANCE</color>";
				EnduD = "         <color=#FFAB00>ENDURANCE</color>";
				Endu = "la quantité d'endurance maximum";
				ViteT = "<color=#6DF0F9>VITESSE</color>";
				ViteD = "         <color=#6DF0F9>VITESSE</color>";
				Vite = "la vitesse de sprint";
				ForcT = "<color=#C4774A>FORCE</color>";
				ForcD = "         <color=#C4774A>FORCE</color>";
				Forc = "la capacité à porter des charges lourdes";
				AgiT = "<color=#00FF80>AGILITE</color>";
				AgiD = "         <color=#00FF80>AGILITE</color>";
				Agi = "la hauteur des sauts";
				CritT = "<color=#ff4444>CRITIQUE</color>";
				CritD = "         <color=#ff4444>CRITIQUE</color>";
				Crit = "Les chance de faire 1 coup critiques avec les armes de corps à corps";
				EnerT = "<color=#F2FC66>ENERGIE</color>";
				EnerD = "         <color=#F2FC66>ENERGIE</color>";
				Ener = "la durée des batteries";
				VisiT = "<color=#ccccff>VISION</color>";
				VisiD = "         <color=#ccccff>VISION</color>";
				Visi = "La durée et la vitesse de recharge de la <color=#ACACE9>Vision nocturne</color> <color=#ff00ff>(Capacité requise)</color>.";
				OxygT = "<color=#3399FF>OXYGENE</color>";
				OxygD = "         <color=#3399FF>OXYGENE</color>";
				Oxyg = "la durée de respiration sous l'eau";
				SpecT = "<color=#5341AB>SPECIAL</color>";
				SpecD = "         <color=#5341AB>SPECIAL</color>";
				Spec = "la quantité d'objet transportable";
				ChanT = "<color=#FF75FB>CHANCE</color>";
				ChanD = "         <color=#FF75FB>CHANCE</color>";
				Chan = "la valeur des objets à collecter";
				WisT = "<color=#ff007f>SAGESSE</color>";
				WisD = "        <color=#ff007f>SAGESSE</color>";
				Wis = "l'exp bonus gagner en tuant des monstres";
				PerT = "<color=#330066>PERCEPTION</color>";
				PerD = "         <color=#330066>PERCEPTION</color>";
				Per = ": Pour débloquer la capacité de <color=#330066>Perception</color>. Permet de detecter les monstres plus facilement dans un rayon de " + int.Parse(SkillConfig.hostConfig["Perception : range / Perception : portée"]) + "m.";
				DoubT = "<color=#00cc66>DOUBLE-SAUT</color>";
				DoubD = "         <color=#00cc66>DOUBLE-SAUT</color>";
				Doub = "Pour débloquer la capacité de <color=#00cc66>Double Saut</color>. Permet d'effectuer un double saut (touche configurable dans les options du jeu).";
				NighT = "<color=#ACACE9>VISION-NUIT</color>";
				NighD = "         <color=#ACACE9>VISION-NUIT</color>";
				Nigh = "Pour débloquer la capacité de <color=#ACACE9>Vision nocturne</color>. Permet d'activer temporairement la vision nocturne (touche configurable dans les options du jeu).";
			}
			else if (bool.Parse(SkillConfig.hostConfig["Res